How to run a migration with Python Alembic by code?

偶尔善良 提交于 2021-02-18 07:01:44

问题


I am trying to migrate a SQL database using sqlAlchemy and Alembic. I would like to make simple migration scripts directly in Python code, and not by using Alembic CLI, as described in the docs.

I only found this SO question on this topic: Using Alembic API from inside application code

Using this question + Flask-Alembic source code, I tried these simple commands. engine is linked to my db & metadata contains the information for the migration.

I think I am very close, and the solution should be in one line of code... I'm struggling.

from alembic.config import Config
from alembic import command, autogenerate
from alembic.script import ScriptDirectory
from alembic.runtime.environment import EnvironmentContext

alembic_cfg = Config()
alembic_cfg.set_main_option("script_location", "migrations")
alembic_cfg.set_main_option("url", "postgresql://user:pass@postgres:5432/mydb")

alembic_script = ScriptDirectory.from_config(alembic_cfg)
alembic_env = EnvironmentContext(alembic_cfg, alembic_script)

conn = engine.connect()
alembic_env.configure(connection=conn, target_metadata=metadata)
alembic_context = alembic_env.get_context()

I am able to use the following commands to see that it works and detects what fields have to migrate :

autogenerate.compare_metadata(alembic_context, metadata)
autogenerate.produce_migrations(alembic_context, metadata)

However, I am not able to run the migrations. I tried several commands, and always get an error...

Ex, if I run:

with alembic_env.begin_transaction():
    alembic_env.run_migrations()

I get :

/usr/local/lib/python2.7/site-packages/alembic/runtime/migration.pyc in run_migrations(self, **kw)
    301         head_maintainer = HeadMaintainer(self, heads)
    302 
--> 303         for step in self._migrations_fn(heads, self):
    304             with self.begin_transaction(_per_migration=True):
    305                 if self.as_sql and not head_maintainer.heads:

TypeError: 'NoneType' object is not callable

Could anyone help me. I think the solution is a one-liner, but I cannot find how to run the migration on my database...

For information, I have never done any migration on this DB with Alembic, maybe there is the need of an "init" ?

Thanks a lot.


回答1:


for step in self._migrations_fn(heads, self):

Here we shall describe in what order you want to migrate. The sequence consists of steps, each of have step.migration_fn(**kw).

How to fix

The last step you need is add _migrations_fn while you do alembic_env.configure.

def do_upgrade(revision, context):
    return alembic_script._upgrade_revs(script.get_heads(), revision)

alembic_env.configure(connection=conn, target_metadata=metadata, fn=do_upgrade)

script.get_heads() returns the last migration. Replace, if you need a specific revision, instead of the last.

Related links:

  • Using Alembic API from inside application code

    https://bitbucket.org/davidism/flask-alembic/src/e036f063af1ba667c74560264639a93d812dfd51/flask_alembic/extension.py?at=default&fileviewer=file-view-default#extension.py-324



来源:https://stackoverflow.com/questions/39021059/how-to-run-a-migration-with-python-alembic-by-code

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