Working with Branch Labels
使用分支标注
To satisfy the use case where an environment has long-lived branches, especially independent branches as will be discussed in the next section, Alembic supports the concept of branch labels. These are string values that are present within the migration file, using the new identifier branch_labels
. For example, if we want to refer to the “shopping cart” branch using the name “shoppingcart”, we can add that name to our file 27c6a30d7c24_add_shopping_cart_table.py
:
为了满足环境具有长期存在的分支的用例,尤其是下一节将讨论的独立分支,Alembic 支持分支标签的概念。 这些是迁移文件中存在的字符串值,使用新的标识符
branch_labels
。 例如,如果我们想使用名称“shopping cart”来引用“购物车”分支,我们可以将该名称添加到我们的文件27c6a30d7c24_add_shopping_cart_table.py
中:
"""add shopping cart table
"""
# revision identifiers, used by Alembic.
revision = '27c6a30d7c24'
down_revision = '1975ea83b712'
branch_labels = ('shoppingcart',)
# ...
The branch_labels
attribute refers to a string name, or a tuple of names, which will now apply to this revision, all descendants of this revision, as well as all ancestors of this revision up until the preceding branch point, in this case 1975ea83b712
. We can see the shoppingcart
label applied to this revision:
branch_labels
属性指的是字符串名称或名称元组,现在将应用于此修订版、此修订版的所有后代,以及此修订版的所有祖先,直到前一个分支点,在本例中为1975ea83b712
。 我们可以看到应用于此修订版的shoppingcart
标签:
$ alembic history
1975ea83b712 -> 27c6a30d7c24 (shoppingcart) (head), add shopping cart table
1975ea83b712 -> ae1027a6acf (head), add a column
<base> -> 1975ea83b712 (branchpoint), create account table
With the label applied, the name shoppingcart
now serves as an alias for the 27c6a30d7c24
revision specifically. We can illustrate this by showing it with alembic show
:
应用标签后,名称
shoppingcart
现在专门用作27c6a30d7c24
修订版的别名。 我们可以通过alembic show
展示它来说明这一点:
$ alembic show shoppingcart
Rev: 27c6a30d7c24 (head)
Parent: 1975ea83b712
Branch names: shoppingcart
Path: foo/versions/27c6a30d7c24_add_shopping_cart_table.py
add shopping cart table
Revision ID: 27c6a30d7c24
Revises: 1975ea83b712
Create Date: 2014-11-20 13:03:11.436407
However, when using branch labels, we usually want to use them using a syntax known as “branch at” syntax; this syntax allows us to state that we want to use a specific revision, let’s say a “head” revision, in terms of a specific branch. While normally, we can’t refer to alembic upgrade head
when there’s multiple heads, we can refer to this head specifcally using shoppingcart@head
syntax:
但是,在使用分支标签时,我们通常希望使用一种称为 “branch at” 的语法来使用它们; 这种语法允许我们声明我们想要使用一个特定的修订,比如说一个 “head” 修订,就特定的分支而言。 虽然通常情况下,当有多个
head
时,我们不能引用alembic upgrade head
,但我们可以使用shoppingcart@head
语法专门引用这个head
:
$ alembic upgrade shoppingcart@head
INFO [alembic.migration] Running upgrade 1975ea83b712 -> 27c6a30d7c24, add shopping cart table
The shoppingcart@head
syntax becomes important to us if we wish to add new migration files to our versions directory while maintaining multiple branches. Just like the upgrade
command, if we attempted to add a new revision file to our multiple-heads layout without a specific parent revision, we’d get a familiar error:
如果我们希望在维护多个分支的同时将新的迁移文件添加到版本目录中,
shoppingcart@head
语法对我们来说变得很重要。 就像upgrade
命令一样,如果我们试图在没有特定父版本的情况下向多头布局添加新的版本文件,我们会得到一个熟悉的错误:
$ alembic revision -m "add a shopping cart column"
FAILED: Multiple heads are present; please specify the head revision on
which the new revision should be based, or perform a merge.
The alembic revision
command is pretty clear in what we need to do; to add our new revision specifically to the shoppingcart
branch, we use the --head
argument, either with the specific revision identifier 27c6a30d7c24
, or more generically using our branchname shoppingcart@head
:
alembic revision
命令非常清楚我们需要做什么; 为了将我们的新版本专门添加到shoppingcart
分支,我们使用--head
参数,或者使用特定的版本标识符27c6a30d7c24
,或者更一般地使用我们的分支名称shoppingcart@head
:
$ alembic revision -m "add a shopping cart column" --head shoppingcart@head
Generating /path/to/foo/versions/d747a8a8879_add_a_shopping_cart_column.py ... done
alembic history
shows both files now part of the shoppingcart
branch:
alembic history
显示两个文件现在都属于shoppingcart
分支:
$ alembic history
1975ea83b712 -> ae1027a6acf (head), add a column
27c6a30d7c24 -> d747a8a8879 (shoppingcart) (head), add a shopping cart column
1975ea83b712 -> 27c6a30d7c24 (shoppingcart), add shopping cart table
<base> -> 1975ea83b712 (branchpoint), create account table
We can limit our history operation just to this branch as well:
我们也可以将历史操作限制在这个分支上:
$ alembic history -r shoppingcart:
27c6a30d7c24 -> d747a8a8879 (shoppingcart) (head), add a shopping cart column
1975ea83b712 -> 27c6a30d7c24 (shoppingcart), add shopping cart table
If we want to illustrate the path of shoppingcart
all the way from the base, we can do that as follows:
如果我们想说明
shoppingcart
从 base 开始的路径,我们可以这样做:
$ alembic history -r :shoppingcart@head
27c6a30d7c24 -> d747a8a8879 (shoppingcart) (head), add a shopping cart column
1975ea83b712 -> 27c6a30d7c24 (shoppingcart), add shopping cart table
<base> -> 1975ea83b712 (branchpoint), create account table
We can run this operation from the “base” side as well, but we get a different result:
我们也可以从“base”端运行这个操作,但是我们得到了不同的结果:
1975ea83b712 -> ae1027a6acf (head), add a column
27c6a30d7c24 -> d747a8a8879 (shoppingcart) (head), add a shopping cart column
1975ea83b712 -> 27c6a30d7c24 (shoppingcart), add shopping cart table
<base> -> 1975ea83b712 (branchpoint), create account table
When we list from shoppingcart@base
without an endpoint, it’s really shorthand for -r shoppingcart@base
:heads, e.g. all heads, and since shoppingcart@base
is the same “base” shared by the ae1027a6acf
revision, we get that revision in our listing as well. The <branchname>@base
syntax can be useful when we are dealing with individual bases, as we’ll see in the next section.
当我们从
shoppingcart@base
列出没有端点时,它实际上是 -rshoppingcart@base
:heads 的简写,例如 所有的head,因为shoppingcart@base
是ae1027a6acf
修订版共享的同一个“基础”,我们也可以在我们的清单中获得该修订版。<branchname>@base
语法在我们处理单个碱基时很有用,我们将在下一节中看到。
The <branchname>@head
format can also be used with revision numbers instead of branch names, though this is less convenient. If we wanted to add a new revision to our branch that includes the un-labeled ae1027a6acf
, if this weren’t a head already, we could ask for the “head of the branch that includes ae1027a6acf” as follows:
<branchname>@head
格式也可以与修订号一起使用,而不是分支名称,尽管这样不太方便。 如果我们想向我们的分支添加一个包含未标记的ae1027a6acf
的新修订,如果这还不是一个head,我们可以要求“包含 ae1027a6acf 的分支的head”,如下所示:
$ alembic revision -m "add another account column" --head ae10@head
Generating /path/to/foo/versions/55af2cb1c267_add_another_account_column.py ... done