I\'m using Alembic with SQL Alchemy. With SQL Alchemy, I tend to follow a pattern where I don\'t store the connect string with the versioned code. Instead I have file secr
I was bumping into this problem as well since we're running our migrations from our local machines. My solution is to put environment sections in the alembic.ini
which stores the database config (minus the credentials):
[local]
host = localhost
db = dbname
[test]
host = x.x.x.x
db = dbname
[prod]
host = x.x.x.x
db = dbname
Then I put the following in the env.py
so the user can pick their environment and be prompted for the credentials:
from alembic import context
from getpass import getpass
...
envs = ['local', 'test', 'prod']
print('Warning: Do not commit your database credentials to source control!')
print(f'Available migration environments: {", ".join(envs)}')
env = input('Environment: ')
if env not in envs:
print(f'{env} is not a valid environment')
exit(0)
env_config = context.config.get_section(env)
host = env_config['host']
db = env_config['db']
username = input('Username: ')
password = getpass()
connection_string = f'postgresql://{username}:{password}@{host}/{db}'
context.config.set_main_option('sqlalchemy.url', connection_string)
You should store your credentials in a password manager that the whole team has access to, or whatever config/secret store you have available. Though, with this approach the password is exposed to your local clip board - an even better approach would be to have env.py
directly connect to your config/secret store API and pull out the username/password directly but this adds a third party dependency.