I had a database which already had migrations. I added a second database, re-running flask db init --multidb as you suggested at https://github.com/miguelgrinberg/Flask-Migrate/issues/179. Worked fine. But, when I want to upgrade or downgrade one of the old migrations (old means, they where created by flask db migrate when I had only one database), I get the error
Traceback (most recent call last):
File "/[...]/bin/flask", line 11, in <module>
sys.exit(main())
File "/[...]/lib/python3.6/site-packages/flask/cli.py", line 507, in main
cli.main(args=args, prog_name=name)
File "/[...]/lib/python3.6/site-packages/flask/cli.py", line 374, in main
return AppGroup.main(self, *args, **kwargs)
File "/[...]/lib/python3.6/site-packages/click/core.py", line 697, in main
rv = self.invoke(ctx)
File "/[...]/lib/python3.6/site-packages/click/core.py", line 1066, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/[...]/lib/python3.6/site-packages/click/core.py", line 1066, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/[...]/lib/python3.6/site-packages/click/core.py", line 895, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/[...]/lib/python3.6/site-packages/click/core.py", line 535, in invoke
return callback(*args, **kwargs)
File "/[...]/lib/python3.6/site-packages/click/decorators.py", line 17, in new_func
return f(get_current_context(), *args, **kwargs)
File "/[...]/lib/python3.6/site-packages/flask/cli.py", line 251, in decorator
return __ctx.invoke(f, *args, **kwargs)
File "/[...]/lib/python3.6/site-packages/click/core.py", line 535, in invoke
return callback(*args, **kwargs)
File "/[...]/lib/python3.6/site-packages/flask_migrate/cli.py", line 132, in upgrade
_upgrade(directory, revision, sql, tag, x_arg)
File "/[...]/lib/python3.6/site-packages/flask_migrate/__init__.py", line 244, in upgrade
command.upgrade(config, revision, sql=sql, tag=tag)
File "/[...]/lib/python3.6/site-packages/alembic/command.py", line 174, in upgrade
script.run_env()
File "/[...]/lib/python3.6/site-packages/alembic/script/base.py", line 416, in run_env
util.load_python_file(self.dir, 'env.py')
File "/[...]/lib/python3.6/site-packages/alembic/util/pyfiles.py", line 93, in load_python_file
module = load_module_py(module_id, path)
File "/[...]/lib/python3.6/site-packages/alembic/util/compat.py", line 68, in load_module_py
module_id, path).load_module(module_id)
File "<frozen importlib._bootstrap_external>", line 399, in _check_name_wrapper
File "<frozen importlib._bootstrap_external>", line 823, in load_module
File "<frozen importlib._bootstrap_external>", line 682, in load_module
File "<frozen importlib._bootstrap>", line 251, in _load_module_shim
File "<frozen importlib._bootstrap>", line 675, in _load
File "<frozen importlib._bootstrap>", line 655, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 678, in exec_module
File "<frozen importlib._bootstrap>", line 205, in _call_with_frames_removed
File "migrations/env.py", line 158, in <module>
run_migrations_online()
File "migrations/env.py", line 138, in run_migrations_online
context.run_migrations(engine_name=name)
File "<string>", line 8, in run_migrations
File "/[...]/lib/python3.6/site-packages/alembic/runtime/environment.py", line 807, in run_migrations
self.get_context().run_migrations(**kw)
File "/[...]/lib/python3.6/site-packages/alembic/runtime/migration.py", line 321, in run_migrations
step.migration_fn(**kw)
TypeError: upgrade() got an unexpected keyword argument 'engine_name'
This is, because flask-Migrate is passing the engine_name as a parameter now, which it (understandably) didn't do before flask db init --multidb. I can fix this by refactoring each instance of def upgrade() to def upgrade(**kwargs) or def upgrade(engine_name) and analogously for ocurrences of def downgrade() in the existing migration files. But to me, it feels paradigmatically wrong to change anything in a migration. Maybe I am wrong with this, but is there a possibility for flask-Migrate to prevent me from refactoring the migrations?
I actually missed this difference between the migration scripts for one vs. multi database. I honestly don't think there is anything wrong with modifying existing migration scripts, as long as you don't change the actual migration logic.
If you look at one of the multi-db migrations you'll find what you need to change, you'll simply need to replace the upgrade and downgrade functions with:
def upgrade(engine_name):
globals()["upgrade_%s" % engine_name]()
def downgrade(engine_name):
globals()["downgrade_%s" % engine_name]()
Then rename your original upgrade() and downgrade() to upgrade_() and downgrade_(), and finally add empty upgrade_dbname() and downgrade_dbname() functions for your additional database(s).
@jonathan-scholbach & @miguelgrinberg I found the question above and also this one [#179] (https://github.com/miguelgrinberg/Flask-Migrate/issues/179) extremely helpful.
I really appreciate it. Thank you very much!
Most helpful comment
I actually missed this difference between the migration scripts for one vs. multi database. I honestly don't think there is anything wrong with modifying existing migration scripts, as long as you don't change the actual migration logic.
If you look at one of the multi-db migrations you'll find what you need to change, you'll simply need to replace the upgrade and downgrade functions with:
Then rename your original
upgrade()anddowngrade()toupgrade_()anddowngrade_(), and finally add emptyupgrade_dbname()anddowngrade_dbname()functions for your additional database(s).