如果未检测到任何更改,如何防止 alembic revision --autogenerate 制作修订文件?

How to prevent alembic revision --autogenerate from making revision file if it has not detected any changes?

我有一个项目,我在其中使用 SQLAlchemy 作为模型,并且我正在尝试集成 Alembic 来进行迁移。当我更改模型并且 Alembic 看到模型已更改时,一切都按预期工作 -> 它使用命令创建良好的迁移文件: alembic revision --autogenerate -m "model changed"

但是当我没有更改模型中的任何内容并且我使用相同的命令时:

alembic revision --autogenerate -m "should be no migration"

revision 给我 'empty' 这样的修订文件:

"""next

Revision ID: d06d2a8fed5d
Revises: 4461d5328f57
Create Date: 2021-12-02 18:09:42.208607

"""
from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = 'd06d2a8fed5d'
down_revision = '4461d5328f57'
branch_labels = None
depends_on = None


def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    pass
    # ### end Alembic commands ###


def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    pass
    # ### end Alembic commands ###

这个文件的用途是什么?当 alembic revision --autogenerate 看不到任何更改时,我可以阻止创建此 'empty file' 吗? 比较我使用 Django 时和输入命令时它的内部迁移:

python manage.py makemigrations

我得到如下输出:

No changes detected

并且没有创建迁移文件。 有没有办法对 Alembic 修订做同样的事情? 或者是否有其他命令可以检查模型是否有变化,如果有,我可以简单地 运行 alembic 修订和升级?

要回答这个问题,我们需要了解蒸馏器的工作原理。 基本上,当你 运行 alembic 修订时,它会创建一个修订并保存 revisioniddown_revision 然后像队列一样排列它们......如果你检查你的数据库,你会在alembic_versiontable。 每个修订版都需要一个文件来处理迁移,因此如果没有它的相关文件就无法进行修订...因为在重建项目时 alembic 如何自动从 base 迁移到最新修订版?就像是少了一块拼图。

长话短说不,没有相关文件就无法进行修订。

P.S。关于 Django 和其他框架,它们有一个非常强大的迁移脚本,因此它可以处理迁移。在这种情况下,框架的迁移器会检查您的模型文件并发现没有任何变化,因此它不会创建任何修订!这就是为什么您看不到迁移文件夹中和数据库的 alembic_version table 中没有任何更改的原因。

接受的答案没有回答问题。 正确答案是:是的,您可以调用 alembic revision --autogenerate 并确保只有在发生更改时才会生成修订文件:

根据 alembic 的 documentation

在 Flask-Migrate 中实现(恰好在 this 文件中),它只是对 env.py 的更改以说明所需的功能,即如果没有,则不会自动生成修订模型更改。

您仍然会 运行 alembic revision --autogenerate -m "should be no migration",但是您对 env.py 所做的更改简而言之:

    def run_migrations_online():
        # almost identical to Flask-Migrate (Thanks miguel!)    
        # this callback is used to prevent an auto-migration from being generated
        # when there are no changes to the schema
    
        def process_revision_directives(context, revision, directives):
            if config.cmd_opts.autogenerate:
                script = directives[0]
                if script.upgrade_ops.is_empty():
                    directives[:] = []
                    print('No changes in schema detected.')
    
        connectable = engine_from_config(
            config.get_section(config.config_ini_section),
            prefix="sqlalchemy.",
            poolclass=pool.NullPool,
        )
    
        with connectable.connect() as connection:
            context.configure(
                connection=connection,
                target_metadata=target_metadata,
                process_revision_directives=process_revision_directives
            )
    
            with context.begin_transaction():
                context.run_migrations() 

现在,您可以轻松地调用 alembic revision --autogenerate,而不必冒创建新的空修订版的风险。