soa*_*gem 2 sqlalchemy database-migration alembic
我将Alembic用作Python项目的数据库迁移工具。当我运行这样的命令时:
alembic revision -m "adding a column"
Run Code Online (Sandbox Code Playgroud)
...它将添加一个新文件alembic/versions/xxxxxxxxxxxx_adding_a_column.py,该文件名为where xxxxxxxxxxxx是随机生成的12位数字的哈希。
从使人可读的角度来看,这有点问题,因为这意味着当查看alembic/versions目录时,所有文件将以随机顺序出现,而不是按顺序/时间顺序出现。
Alembic中是否有任何选项可确保这些前缀修订ID是连续的?我想我可以手动重命名文件,然后更新引用,但是我想知道是否已经有了类似的功能。
小智 17
我发现如何在我的情况下做到这一点,无需额外的 bash 脚本,只需 env.py 中的一些突变魔法。也许它会对某人有所帮助。
Alembic 具有强大的功能,可以自定义生成的修订版本,因此我们可以在此级别编写覆盖:
# env.py
def process_revision_directives(context, revision, directives):
# extract Migration
migration_script = directives[0]
# extract current head revision
head_revision = ScriptDirectory.from_config(context.config).get_current_head()
if head_revision is None:
# edge case with first migration
new_rev_id = 1
else:
# default branch with incrementation
last_rev_id = int(head_revision.lstrip('0'))
new_rev_id = last_rev_id + 1
# fill zeros up to 4 digits: 1 -> 0001
migration_script.rev_id = '{0:04}'.format(new_rev_id)
...
# then use it context.configure
context.configure(
...
process_revision_directives=process_revision_directives,
)
Run Code Online (Sandbox Code Playgroud)
如果您还想将其用于创建的修订版,--autogenerate则应revision_environment在中将其设置为 truealembic.ini
Sup*_*oot 12
听起来,您对顺序列出的修订文件更感兴趣,而不是对顺序排列的修订ID感兴趣。前者无需更改修订ID的生成方式即可实现。
alembic.ini运行时生成的文件alembic init alembic包含一个部分,用于配置修订文件的命名:
# template used to generate migration files
# file_template = %%(rev)s_%%(slug)s
Run Code Online (Sandbox Code Playgroud)
这是来自文档的解释:
file_template-这是用于生成新迁移文件的命名方案。当前值是默认值,因此已注释掉。可用的令牌包括:
- %%(rev)s-版本ID
- %%(slug)s-从修订消息派生的截断的字符串
- %%(年)d,%%(月).2d,%%(天).2d,%%(小时).2d,%%(分钟).2d,%%(秒).2d-创建日期,默认情况下为datetime.datetime.now(),除非也使用了时区配置选项。
因此,添加file_template = %%(year)d-%%(month).2d-%%(day).2d_%%(rev)s_%%(slug)s到alembic.ini会将您的修订命名为2018-11-15_xxxxxxxxxxxx_adding_a_column.py。
我发现了这个问题:https : //bitbucket.org/zzzeek/alembic/issues/371/add-unixtime-stamp-to-start-of-versions为我指出了正确的方向。
时间戳不一定告诉您哪个文件是最新的,因为允许分支。“学术历史”本应成为对此的最好的真理来源。
因此,文件命名解决方案将不能保证在目录中按逻辑顺序进行迁移(但会对IMO有所帮助)。可以针对具有顺序ID的情况提出相同的论点。
如果确实要指定自己的修订标识符,请--rev-id在命令行上使用该标志。
例如:
alembic revision -m 'a message' --rev-id=1
生成了一个文件1_a_message.py:
"""a message
Revision ID: 1
Revises:
Create Date: 2018-11-15 13:40:31.228888
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '1'
down_revision = None
branch_labels = None
depends_on = None
def upgrade():
pass
def downgrade():
pass
Run Code Online (Sandbox Code Playgroud)
因此,您绝对可以自己管理修订标识符。编写bash脚本以触发修订版本的生成,自动传递基于datetime的时间rev_id,例如--rev-id=<current datetime>管理目录中列出的顺序,将是微不足道的。
如果未指定版本ID,则在以下位置rev_id()找到的函数将alembic.util.langhelpers被调用:
def rev_id():
return uuid.uuid4().hex[-12:]
Run Code Online (Sandbox Code Playgroud)
rev_id()在Alembic源中,对函数的调用是硬编码的,因此,如果不对函数进行猴子修补,将很难覆盖该行为。您可以创建一个库的派生分支,然后重新定义该函数,或者将其用于生成ID的函数配置为可配置的。
我制作了一个脚本,根据已存在的匹配该####_模式的迁移数量来自动增加修订号。这是一个 TLDR 版本。我将其保存为migrations.sh并更改第2行中的路径
#!/usr/bin/env bash
NEXT_ID=`ls kennel/db/versions/* | grep -P '/\d{4}_.*\.py$' | wc -l`
alembic revision -m $@ --rev-id=`printf "%04d" ${NEXT_ID}`
Run Code Online (Sandbox Code Playgroud)
然后你可以像这样使用它:
./migrations.sh migration_name
# or
./migrations.sh migration_name --autogenerate
Run Code Online (Sandbox Code Playgroud)
完整的脚本有文档并使用默认值,--autogenerate可以使用--empty标志禁用默认值。
https://gist.github.com/chriscauley/cf0b038d055076a2a30de43526d4150e
| 归档时间: |
|
| 查看次数: |
1104 次 |
| 最近记录: |