Is it possible to store the alembic connect string outside of alembic.ini? Is it possible to store the alembic connect string outside of alembic.ini? python python

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 codeimport config as ems_configconfig.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)s@35.197.196.146/nozzle-website

env.py

import osfrom logging.config import fileConfigfrom sqlalchemy import engine_from_configfrom sqlalchemy import poolfrom 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 envsection = config.config_ini_sectionconfig.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:

  1. 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
  2. Use the URL in offline mode:

    def run_migrations_offline():    ...    url = get_url()    context.configure(        url=url, target_metadata=target_metadata, literal_binds=True)    ...
  3. Use the URL in online mode by using create_engine instead of engine_from_config:

    def run_migrations_online():    ...    connectable = create_engine(get_url())    with connectable.connect() as connection:    ...