Preamble
It's actually pretty important to be able to do this. Models developed using flask-sqlalchemy
cannot be used outside of flask
itself. There is flask-migrate
but that requires flask-sqlalchemy
be used. There are guides such as this that explain the setup for the database, and even flask
itself with SQLAlchemy in Flask to avoid this restriction. When it comes to alembic
for this setup, I couldn't find anything. So, this is the best I have atm and would welcome other answers.
Using command
This is the best I have got to date using the commands
module when pulling in arbitrary SQLAlchemy
models for a project called ex_machina
with multiple blueprints.
database.py on the top level of the project.
import os
from alembic import command
from alembic.config import Config as AlembicConfig
from sqlalchemy import create_engine, MetaData
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from ex_machina.config import Config
engine = create_engine(Config.CONN_STRING)
db_session = scoped_session(sessionmaker(autocommit=False,
autoflush=False,
bind=engine))
meta = MetaData(naming_convention={
"ix": "ix_%(column_0_label)s",
"uq": "uq_%(table_name)s_%(column_0_name)s",
"ck": "ck_%(table_name)s_%(column_0_name)s",
"fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
"pk": "pk_%(table_name)s"
})
Base = declarative_base(metadata=meta)
Base.query = db_session.query_property()
def _get_alembic_config():
directory = os.path.dirname(__file__)
alembic_directory = os.path.join(directory, 'alembic')
alembic_cfg = AlembicConfig()
alembic_cfg.set_main_option('sqlalchemy.url',
Config.CONN_STRING)
alembic_cfg.set_main_option('script_location', alembic_directory)
return alembic_cfg
def _migrate():
import ex_machina.admin.models
import ex_machina.auth.models
import ex_machina.departments.models
import ex_machina.home.models
alembic_cfg = _get_alembic_config()
command.stamp(alembic_cfg, 'head')
command.revision(alembic_cfg, autogenerate=True)
def _upgrade():
alembic_cfg = _get_alembic_config()
command.upgrade(alembic_cfg, 'head')
def _downgrade(hash_):
alembic_cfg = _get_alembic_config()
command.downgrade(alembic_cfg, hash_)
def init_db():
import ex_machina.admin.models
import ex_machina.auth.models
import ex_machina.departments.models
import ex_machina.home.models
Base.metadata.create_all(bind=engine)
alembic.env.py
# add your model's MetaData object here
# for 'autogenerate' support
# from myapp import mymodel
# target_metadata = mymodel.Base.metadata
# target_metadata = None
from ex_machina import database
target_metadata = database.Base.metadata
I don't like it but you can wrap a CLI around this proof of concept. I look forward to a better guide.