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

后端 未结 10 1614
[愿得一人]
[愿得一人] 2021-01-30 15:41

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

10条回答
  •  滥情空心
    2021-01-30 16:22

    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.

提交回复
热议问题