没有迁移中的蒸馏器自动生成与瓶-SQLAlchemy中检测到的变化(No changes detec

2019-06-28 08:22发布

我遇到了麻烦蒸馏器来自动生成从改变候选人迁移到使用类db.Model代替(瓶-SQLAlchemy中) Base

我修改env.py创建我的瓶的应用程序,导入所有相关模型,初始化数据库,然后运行迁移:

...
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()
...

这种方法工作正常drop_all() create_all()例如,重新创建单元测试的测试分贝时),但似乎在这种情况下落空。 自动生成的版本脚本总是空的升级和降级方法, 例如

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

我的变化包括重命名列,更改列定义 ,不只是改变以指数和外键。

有没有人有使用蒸馏器与瓶-SQLAlchemy的? 任何想法,我要去哪里错了吗?

非常感谢!

Answer 1:

蒸馏器不能自动检测表或列重命名。 默认情况下,它不会查找列类型的变化要么,但compare_type选项可以为此启用。

从蒸馏器文件摘录:

自动生成默认会检测:

  • 表添加,删除。
  • 列添加,删除。
  • 对列可为空的状态变化。

自动生成可任选地检测:

  • 列类型的变化。 如果设置,这将发生compare_type=TrueEnvironmentContext.configure() 该功能适用​​于大多数情况下,但默认是关闭的,这样它可以在目标模式首先进行测试。 它也可以被路经此地可调用定制; 看到功能的使用说明。
  • 服务器默认的变化。 如果设置,这将发生compare_server_default=TrueEnvironmentContext.configure() 这项功能非常适用于简单的案件,但不能总是产生准确的结果。 PostgreSQL后端将实际调用“检测”和“元数据”值对数据库以确定等价。 该功能默认是关闭的,这样它可以在目标模式首先进行测试。 像类型的比较,也可以通过使一个可调用定制; 看到功能的使用说明。

自动生成无法检测:

  • 表名称的变化。 这些会出来作为两个不同的表的加/减,应该是手工编辑成一个名称的改变,而不是。
  • 列名的变化。 如表名改变时,这些被检测为一个柱插/分对,这并不是在所有相同的名称的变化。
  • 特别SQLAlchemy的类型,如Enum上不支持后台时产生ENUM直接-这是因为在非支持数据库这样的类型,即A的表示CHAR+CHECK约束,可以是任何种类的CHAR+CHECK 。 对于SQLAlchemy的决定,这实际上是一个ENUM就只能是猜测,这东西通常是一个坏主意。 要在这里实现自己的“猜测”功能,使用sqlalchemy.events.DDLEvents.column_reflect()事件来改变通过了某些列,并可能在SQLAlchemy的类型sqlalchemy.events.DDLEvents.after_parent_attach()拦截不必要的CHECK约束。

自动生成目前不能,但最终会发现:

  • 自由站立约束添加,删除,像CHECKUNIQUEFOREIGN KEY -这些都还没有实现。 现在你会得到内新表,PK和FK约束约束的“降级”到先前存在的表,并CHECK了SQLAlchemy的“模式”类型产生的约束BooleanEnum
  • 指数添加,删除 - 尚未实现。
  • 顺序添加,删除 - 尚未实现。

更新:一些在这最后的列表中的项目在蒸馏器0.7.x版本的支持。



Answer 2:

我的错误是,试图在最终状态已经创造我用分贝初始迁移,以为它会发现,它没有现有版本和基于它的模型。 我得到空的版本,直到我删除了数据库中的所有表,然后它能正常工作。



Answer 3:

尝试烧瓶,蒸馏器https://github.com/tobiasandtobias/flask-alembic

我昨天试了一下。 它工作正常,我只是drop操作。 他们不能在SQLite的(工作https://bitbucket.org/zzzeek/alembic/issue/21/column-renames-not-supported-on-sqlite )。

我已经用它的方式。 首先,我用python manage.py migrate revision --autogenerate创造源码数据库空表。 它会产生这样的迁移

def upgrade():
    ### commands auto generated by Alembic - please adjust! ###
    op.create_table('users_user',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('name', sa.String(length=50), nullable=True),
    sa.Column('email', sa.String(length=120), nullable=True),
    sa.Column('password', sa.String(length=20), nullable=True),
    sa.Column('role', sa.SmallInteger(), nullable=True),
    sa.Column('status', sa.SmallInteger(), nullable=True),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('email'),
    sa.UniqueConstraint('name')
)
### end Alembic commands ###

def downgrade():
    ### commands auto generated by Alembic - please adjust! ###
    op.drop_table('users_user')
    ### end Alembic commands ###

然后- python manage.py migrate upgrade head

然后,我添加一个新的列test = db.Column(db.String(20))到用户模型和运行这个命令python manage.py migrate revision --autogenerate -m 'test field at users'

这产生这样的迁移:

def upgrade():
    ### commands auto generated by Alembic - please adjust! ###
    op.add_column('users_user', sa.Column('test', sa.String(length=20), nullable=True))
    ### end Alembic commands ###


def downgrade():
    ### commands auto generated by Alembic - please adjust! ###
    op.drop_column('users_user', 'test')
    ### end Alembic commands ###


Answer 4:

如果您发现该功能,你需要不alembic.In这种情况下,在支持

  1. 删除该表(或列)则迁移

  2. 添加表(或列)当年再次迁移

这也适用于枚举类型的变化



文章来源: No changes detected in Alembic autogeneration of migrations with Flask-SQLAlchemy