Why Flask-migrate Cannot Upgrade When Drop Column
Solution 1:
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
Solution 2:
I do not know have you solved the problem. But I find a very concise solution: you can add this to the bottom of your init.py file. Afterwards, delete and rebuild your migrations:
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.
Solution 3:
change the migrations/env.py, doc link is http://alembic.readthedocs.org/en/latest/cookbook.html
add render_as_batch=True
in context.configure
defrun_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.htmldefprocess_revision_directives(context, revision, directives):
ifgetattr(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()
Solution 4:
When you initializing the migrate, simply add "render_as_batch=True", like so:
migrate = Migrate(app, db, render_as_batch=True)
manager = Manager(app)
That worked for me
Post a Comment for "Why Flask-migrate Cannot Upgrade When Drop Column"