Here's what I've learned after hooking up my software to alembic
:
Is there a way to call alembic from inside my Python code?
Yes. As of this writing the main entry point for alembic is alembic.config.main
, so you can import it and call it yourself, for example:
import alembic.config
alembicArgs = [
'--raiseerr',
'upgrade', 'head',
]
alembic.config.main(argv=alembicArgs)
Note that alembic looks for migrations in the current directory (i.e., os.getcwd()). I've handled this by using os.chdir(migration_directory)
before calling alembic, but there may be a better solution.
Can I specify a new database location from the command line without editing the .ini file?
Yes. The key lies in the -x
command line argument. From alembic -h
(surprisingly, I wasn't able to find a command line argument reference in the docs):
optional arguments:
-x X Additional arguments consumed by custom env.py
scripts, e.g. -x setting1=somesetting -x
setting2=somesetting
So you can create your own parameter, e.g. dbPath
, and then intercept it in env.py
:
alembic -x dbPath=/path/to/sqlite.db upgrade head
then for example in env.py
:
def run_migrations_online():
# get the alembic section of the config file
ini_section = config.get_section(config.config_ini_section)
# if a database path was provided, override the one in alembic.ini
db_path = context.get_x_argument(as_dictionary=True).get('dbPath')
if db_path:
ini_section['sqlalchemy.url'] = db_path
# establish a connectable object as normal
connectable = engine_from_config(
ini_section,
prefix='sqlalchemy.',
poolclass=pool.NullPool)
# etc
Of course, you can supply the -x parameter using argv
in alembic.config.main
, too.
I agree with @davidism about using migrations vs metadata.create_all()
:)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…