Is it possible to store the alembic connect string outside of alembic.ini?
I had the very same problem yesterday and found a following solution to work.
I do the following in alembic/env.py
:
# this is the Alembic Config object, which provides
# access to the values within the .ini file in use.
config = context.config
# this will overwrite the ini-file sqlalchemy.url path
# with the path given in the config of the main code
import config as ems_config
config.set_main_option('sqlalchemy.url', ems_config.config.get('sql', 'database'))
ems_config
is an external module that holds my configuration data.
config.set_main_option(...)
essentially overwrites the sqlalchemy.url
key in the [alembic]
section of the alembic.ini
file. In my configuration I simply leave it black.
The simplest thing I could come up with to avoid commiting my user/pass was to a) add in interpolation strings to the alembic.ini
file, and b) set these interpolation values in env.py
alembic.ini
sqlalchemy.url = postgresql://%(DB_USER)s:%(DB_PASS)[email protected]/nozzle-website
env.py
import os
from logging.config import fileConfig
from sqlalchemy import engine_from_config
from sqlalchemy import pool
from alembic import context
# this is the Alembic Config object, which provides
# access to the values within the .ini file in use.
config = context.config
# here we allow ourselves to pass interpolation vars to alembic.ini
# fron the host env
section = config.config_ini_section
config.set_section_option(section, "DB_USER", os.environ.get("DB_USER"))
config.set_section_option(section, "DB_PASS", os.environ.get("DB_PASS"))
...
Alembic documentation suggests using create_engine
with the database URL (instead of modifying sqlalchemy.url in code).
Also you should modify run_migrations_offline to use the new URL. Allan Simon has an example on his blog, but in summary, modify env.py to:
-
Provide a shared function to get the URL somehow (here it comes from the command line):
def get_url(): url = context.get_x_argument(as_dictionary=True).get('url') assert url, "Database URL must be specified on command line with -x url=<DB_URL>" return url
-
Use the URL in offline mode:
def run_migrations_offline(): ... url = get_url() context.configure( url=url, target_metadata=target_metadata, literal_binds=True) ...
-
Use the URL in online mode by using
create_engine
instead ofengine_from_config
:def run_migrations_online(): ... connectable = create_engine(get_url()) with connectable.connect() as connection: ...