在使用Flask-SQLAlchemy进行迁移的Alembic自动生成中没有检测到任何更改 [英] No changes detected in Alembic autogeneration of migrations with Flask-SQLAlchemy

查看:822
本文介绍了在使用Flask-SQLAlchemy进行迁移的Alembic自动生成中没有检测到任何更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 db.Model (Flask-SQLAlchemy)而不是 Base



我修改了 env.py 来创建我的Flask应用程序,相关模型,初始化数据库,然后运行迁移:

  ... 
uri ='mysql:// user:password @ host / dbname?charset = utf8'
app = Flask(__ name__)
app.config ['SQLALCHEMY_DATABASE_URI'] = uri
app.config ['SQLALCHEMY_ECHO'] = True
db.init_app(app)
with app.test_request_context():
target_metadata = db.Model.metadata
config.set_main_option('sqlalchemy.url',uri)
if context.is_offline_mode():
run_migrations_offline()
else:
run_migrations_online()
...
$ b $ p

这个方法适用于 drop_all() create_all()(例如,重新创建时单元测试的一个测试分贝),但在这种情况下它似乎下降了。自动生成的版本脚本总是有空的升级和降级方法,例如,

  def upgrade() :Alembic自动生成的
###命令 - 请调整! ###
传递
###结束Alembic命令###


def downgrade():
###由Alembic自动生成的命令 - 请调整! ###
传递
###结束Alembic命令###

我的更改包括重命名列,更改列定义等,不仅仅是对索引和外键的更改



Alembic与Flask-SQLAlchemy?任何想法,我要去哪里错了?

非常感谢!

解决方案

< Alembic无法自动检测表格或列重命名。默认情况下,它也不会查找列类型的变化,但是可以启用 compare_type 选项。



从Alembic文档摘录:

自动生成将默认检测:

$ ul


  • 列的添加,删除。

  • 列的空状态更改



  • Autogenerate可以选择检测:


    • 更改列类型。如果您在EnvironmentContext.configure()上设置了compare_type = True,则会发生这种情况。该功能在大多数情况下运行良好,但默认情况下处于关闭状态,因此可以先在目标模式上对其进行测试。它也可以通过在这里调用来定制;有关详细信息,请参阅该函数的文档。
    • 更改服务器默认值。如果在EnvironmentContext.configure()上设置了compare_server_default = True,则会发生这种情况。此功能适用于简单的情况,但不能总是产生准确的结果。 Postgresql后端将实际调用数据库的检测和元数据值来确定等价性。该功能默认情况下处于关闭状态,因此可以先在目标架构上对其进行测试。像类型比较,也可以通过传递一个可调用的方法来定制;


      自动生成无法检测到:


      • 更改表名。这些将作为两个不同表的添加/删除而出现,并且应该手动编辑为名称更改。

      • 更改列名称。与表名更改一样,这些检测为列添加/删除对,与名称更改完全不同。

      • 特殊的SQLAlchemy类型,例如在后端生成的Enum它不直接支持ENUM - 这是因为这种类型在非支持数据库中的表示,即CHAR + CHECK约束可以是任何种类的CHAR + CHECK。对于SQLAlchemy来确定这实际上是ENUM只是一个猜测,这通常是一个坏主意。要在这里实现自己的猜测函数,请使用sqlalchemy.events.DDLEvents.column_reflect()事件来更改为某些列传递的SQLAlchemy类型,也可能使用sqlalchemy.events.DDLEvents.after_parent_attach()来截获不需要的CHECK约束。 li>


      自动生成目前不能,但最终会检测到:


      • 独立约束添加,删除,如CHECK,UNIQUE,FOREIGN KEY - 这些还没有实现。现在,您将在新表中获取约束,用于将降级到先前存在的表的PK和FK约束以及使用SQLAlchemy模式类型生成的CHECK约束Boolean,Enum。
      • 索引增加,删除 - 尚未执行。

      • 序列添加,删除 - 尚未执行。 $ b

        更新:Alembic 0.7.x版本支持最后一个列表中的一些项目。


        I'm having trouble getting Alembic to autogenerate candidate migrations from changes to classes using db.Model (Flask-SQLAlchemy) instead of Base.

        I've modified env.py to create my Flask app, import all relevant models, initialize the database, and then run migrations:

        ...
        uri = 'mysql://user:password@host/dbname?charset=utf8'
        app = Flask(__name__)
        app.config['SQLALCHEMY_DATABASE_URI'] = uri
        app.config['SQLALCHEMY_ECHO'] = True
        db.init_app(app)
        with app.test_request_context():
            target_metadata = db.Model.metadata
            config.set_main_option('sqlalchemy.url', uri)
            if context.is_offline_mode():
                run_migrations_offline()
            else:
                run_migrations_online()
        ...
        

        This approach works fine for drop_all(), create_all() (for example, when recreating a test db for unit testing), but it seems to fall flat in this case. The auto generated version scripts always have empty upgrade and downgrade methods, e.g.,

        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 ###
        

        My changes have included renaming columns, changing column definitions, etc., not just changes to indices and foreign keys.

        Is anyone out there using Alembic with Flask-SQLAlchemy? Any idea where I'm going wrong?

        Thanks much!

        解决方案

        Alembic cannot automatically detect table or column renames. By default it will not look for column type changes either, but the compare_type option can be enabled for this.

        Excerpt from the Alembic documentation:

        Autogenerate will by default detect:

        • Table additions, removals.
        • Column additions, removals.
        • Change of nullable status on columns.

        Autogenerate can optionally detect:

        • Change of column type. This will occur if you set compare_type=True on EnvironmentContext.configure(). The feature works well in most cases, but is off by default so that it can be tested on the target schema first. It can also be customized by passing a callable here; see the function’s documentation for details.
        • Change of server default. This will occur if you set compare_server_default=True on EnvironmentContext.configure(). This feature works well for simple cases but cannot always produce accurate results. The Postgresql backend will actually invoke the "detected" and "metadata" values against the database to determine equivalence. The feature is off by default so that it can be tested on the target schema first. Like type comparison, it can also be customized by passing a callable; see the function’s documentation for details.

        Autogenerate can not detect:

        • Changes of table name. These will come out as an add/drop of two different tables, and should be hand-edited into a name change instead.
        • Changes of column name. Like table name changes, these are detected as a column add/drop pair, which is not at all the same as a name change.
        • Special SQLAlchemy types such as Enum when generated on a backend which doesn’t support ENUM directly - this because the representation of such a type in the non-supporting database, i.e. a CHAR+ CHECK constraint, could be any kind of CHAR+CHECK. For SQLAlchemy to determine that this is actually an ENUM would only be a guess, something that’s generally a bad idea. To implement your own "guessing" function here, use the sqlalchemy.events.DDLEvents.column_reflect() event to alter the SQLAlchemy type passed for certain columns and possibly sqlalchemy.events.DDLEvents.after_parent_attach() to intercept unwanted CHECK constraints.

        Autogenerate can’t currently, but will eventually detect:

        • Free-standing constraint additions, removals, like CHECK, UNIQUE, FOREIGN KEY - these aren’t yet implemented. Right now you’ll get constraints within new tables, PK and FK constraints for the "downgrade" to a previously existing table, and the CHECK constraints generated with a SQLAlchemy "schema" types Boolean, Enum.
        • Index additions, removals - not yet implemented.
        • Sequence additions, removals - not yet implemented.

        UPDATE: some of the items in this last list are supported in the Alembic 0.7.x releases.

        这篇关于在使用Flask-SQLAlchemy进行迁移的Alembic自动生成中没有检测到任何更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆