是否可以将alembic连接字符串存储在alembic.ini之外?

问题描述 投票:41回答:7

我正在使用Alembic和SQL Alchemy。使用SQL Alchemy,我倾向于遵循一种模式,即我不将连接字符串与版本化代码一起存储。相反,我有文件secret.py包含任何机密信息。我把这个文件名扔在我的.gitignore中,所以它不会在GitHub上结束。

这种模式工作正常,但现在我开始使用Alembic进行迁移。看来我无法隐藏连接字符串。而是在alembic.ini中,将连接字符串放置为configuration parameter

# the 'revision' command, regardless of autogenerate
# revision_environment = false

sqlalchemy.url = driver://user:pass@localhost/dbname

# Logging configuration
[loggers]
keys = root,sqlalchemy,alembi

我担心我会不小心为我的数据库提交一个包含用户名/密码信息的文件。我宁愿将这个连接字符串存储在一个地方,并避免意外将其提交给版本控制的风险。

我有什么选择?

python sqlalchemy alembic
7个回答
46
投票

昨天我遇到了同样的问题,并找到了以下解决方案。我在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是一个保存配置数据的外部模块。

config.set_main_option(...)基本上覆盖了sqlalchemy.url文件的[alembic]部分中的alembic.ini密钥。在我的配置中,我只是把它留黑。


14
投票

Alembic documentation建议使用create_engine和数据库URL(而不是modifying sqlalchemy.url in code)。

您还应修改run_migrations_offline以使用新URL。 Allan Simon在他的博客上有an example,但总的来说,将env.py修改为:

  1. 提供一个共享函数以某种方式获取URL(这里它来自命令行): 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. 在离线模式下使用URL: def run_migrations_offline(): ... url = get_url() context.configure( url=url, target_metadata=target_metadata, literal_binds=True) ...
  3. 使用create_engine而不是engine_from_config在在线模式下使用URL: def run_migrations_online(): ... connectable = create_engine(get_url()) with connectable.connect() as connection: ...

9
投票

所以看起来有效的是在env.py中重新实现引擎创建,这显然是进行这种定制的地方而不是在ini中使用sqlalchemy连接字符串:

engine = engine_from_config(
            config.get_section(config.config_ini_section),
            prefix='sqlalchemy.',
           poolclass=pool.NullPool)

您可以替换并指定自己的引擎配置:

import store
engine = store.engine

事实上,文件seems to imply这是好的:

sqlalchemy.url - 通过SQLAlchemy连接到数据库的URL。实际上,该密钥仅在env.py文件中引用,该文件特定于“通用”配置;可由开发人员自定义的文件。多数据库配置可以在此响应多个键,或者可以引用该文件的其他部分。


4
投票

为了避免提交我的用户/传递,我可以想出的最简单的事情是:a)将插值字符串添加到alembic.ini文件中,以及b)在q​​azxswpoi中设置这些插值值

alembic.ini

env.py

恶女.朋友

sqlalchemy.url = postgresql://%(DB_USER)s:%(DB_PASS)[email protected]/nozzle-website

1
投票

我正在寻找一段时间如何为多数据库管理这个问题

这就是我做的。我有两个数据库:logs和ohlc

根据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")) ... ,我已经设置了类似的蒸馏器

doc

alembic.ini

alembic init --template multidb

恶女.朋友

databases = logs, ohlc
[logs]
sqlalchemy.url = postgresql://botcrypto:botcrypto@localhost/logs
[ohlc]
sqlalchemy.url = postgresql://botcrypto:botcrypto@localhost/ohlc

config.yml

[...]
# this is the Alembic Config object, which provides
# access to the values within the .ini file in use.
config = context.config

# Interpret the config file for Python logging.
# This line sets up loggers basically.
fileConfig(config.config_file_name)
logger = logging.getLogger('alembic.env')

# overwrite alembic.ini db urls from the config file
settings_path = os.environ.get('SETTINGS')
if settings_path:
    with open(settings_path) as fd:
        settings = conf.load(fd, context=os.environ) # loads the config.yml
    config.set_section_option("ohlc", "sqlalchemy.url", settings["databases"]["ohlc"])
    config.set_section_option("logs", "sqlalchemy.url", settings["databases"]["logs"])
else:
    logger.warning('Environment variable SETTINGS missing - use default alembic.ini configuration')
[...]

用法

databases:
    logs: postgresql://botcrypto:[email protected]:5432/logs
    ohlc: postgresql://botcrypto:[email protected]:5432/ohlc

希望它可以帮助!


0
投票

另一种解决方案是创建模板alembic.ini.dist文件并使用您的版本化代码跟踪它,同时忽略VCS中的alembic.ini。

不要在alembic.ini.dist中添加任何机密信息:

SETTINGS=config.yml alembic upgrade head

将代码部署到平台时,将alembic.ini.dist复制到alembic.ini(您的VCS不会跟踪此文件)并使用平台的凭据修改alembic.ini。


0
投票

sqlalchemy.url = ... 你可以编辑env.py来提供除ini文件以外的其他地方的URL。您可以将额外的As Doug T. said参数传递给url函数(kwargs稍后合并到从ini文件中获取的选项),而不是创建新引擎。在这种情况下你可以,例如将加密密码存储在ini文件中,并通过存储在ENV变量中的密码在运行时解密。

engine_from_config
© www.soinside.com 2019 - 2024. All rights reserved.