问题
I'm managing database migrations with Alembic and would like to use the default files generated by alembic init
without any modifications to env.py
(e.g., setting target_metadata) or alembic.ini
(e.g., setting sqlalchemy.url) to manage migrations of my database from scripts.
For example, I'd like to use a command based script like the following:
import os
from alembic.config import Config
from alembic import command
from myapp import db
alembic_cfg = Config(os.path.join(os.path.abspath(os.path.dirname(__file__)), 'alembic.ini'))
alembic_cfg.set_main_option("sqlalchemy.url",
os.environ['DATABASE_URL'])
alembic_cfg.set_main_option("script_location",
os.path.join(os.path.abspath(os.path.dirname(__file__)), '.db_migrations'))
alembic_cfg.set_main_option("target_metadata", db.metadata) # This doesn't work!
command.revision(alembic_cfg, message='Test of new system', autogenerate=True)
command.upgrade(alembic_cfg, 'head')
This all works as desired, except that the indicated line fails, and I don't see a way to set the target_metadata
(other than editing env.py
).
How can I programmatically set the target_metadata
required by Alembic in (something like) the script above, which uses Alembic's command API?
回答1:
The long answer is that you don't set metadata there, you set it when creating the MigrationContext
. Which requires that you create a Config
, then a ScriptDirectory
, then an EnvironmentContext
first. Then you need to use these objects correctly when running revisions to set up the environment yourself.
The short answer is that there are two extensions (that I know of) that integrate Flask-SQLAlchemy with Alembic for you. Flask-Migrate has been around for a while and provides pretty much a straight wrapper around the basic commands from Alembic.
Flask-Alembic (written by me) (not related to an older project of the same name that is not in development) provides tighter integration with Flask and Alembic. It exposes Alembic's internals and works with the Flask dev version, but is newer and more experimental.
They are both actively maintained. If you need to get at the internals, chose Flask-Alembic. If you just need the commands, choose Flask-Migrate.
来源:https://stackoverflow.com/questions/27911685/how-can-i-programmatically-set-the-target-metadata-required-by-alembic-for-use