Why Flask-migrate cannot upgrade when drop column

痞子三分冷 提交于 2019-12-02 15:51:50

SQLite does not support dropping or altering columns. However, there is a way to work around this by making changes at the table level: https://www.sqlite.org/lang_altertable.html

And more usefully for Alembic/Flask-Migrate users, Alembic's batch_alter_table context manager lets you specify the changes in a natural way, and does a little "make new table - copy data - drop old table - rename new table" dance behind the scenes when using SQLite. See: http://alembic.zzzcomputing.com/en/latest/batch.html

So the upgrade() function in your migration file should contain something like:

with op.batch_alter_table('posts') as batch_op:
    batch_op.drop_column('tags')

I'm afraid I don't know why the error changed the second time you tried the upgrade.

As tkisme points out, you can also configure the EnvironmentContext.configure.render_as_batch flag in env.py so that autogenerated migration scripts will use batch_alter_table by default. See: http://alembic.zzzcomputing.com/en/latest/batch.html#batch-mode-with-autogenerate

change the migrations/env.py add render_as_batch=True in context.configure

def run_migrations_online():
    """Run migrations in 'online' mode.

    In this scenario we need to create an Engine
    and associate a connection with the context.

    """

    # this callback is used to prevent an auto-migration from being generated
    # when there are no changes to the schema
    # reference: http://alembic.readthedocs.org/en/latest/cookbook.html
    def process_revision_directives(context, revision, directives):
        if getattr(config.cmd_opts, 'autogenerate', False):
            script = directives[0]
            if script.upgrade_ops.is_empty():
                directives[:] = []
                logger.info('No changes in schema detected.')

    engine = engine_from_config(config.get_section(config.config_ini_section),
                                prefix='sqlalchemy.',
                                poolclass=pool.NullPool)

    connection = engine.connect()
    context.configure(connection=connection,
                      target_metadata=target_metadata,
                      process_revision_directives=process_revision_directives,
                      render_as_batch=True,# this is new feature
                      **current_app.extensions['migrate'].configure_args)

    try:
        with context.begin_transaction():
            context.run_migrations()
    finally:
        connection.close()

I do not know have you solved the problem. But I find a very concise solution: you can do like this:

with app.app_context():
if db.engine.url.drivername == 'sqlite':
    migrate.init_app(app, db, render_as_batch=True)
else:
    migrate.init_app(app, db)

hope to help you.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!