web-dev-qa-db-ja.com

alembic.iniの外にalembic接続文字列を格納することは可能ですか?

SQL AlchemyでAlembicを使用しています。 SQL Alchemyでは、バージョン管理されたコードで接続文字列を保存しないパターンに従う傾向があります。代わりに、ファイルsecret.py機密情報が含まれています。このファイル名を.gitignoreなので、GitHubにはありません。

このパターンは正常に機能しますが、今は移行にAlembicを使用するようになっています。接続文字列を非表示にできないようです。代わりにalembic.iniで、接続文字列を 構成パラメーター として配置します。

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

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

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

データベースのユーザー名/パスワード情報を含むファイルを誤ってコミットしてしまうのではないかと心配です。この接続文字列を1か所に保存し、誤ってバージョン管理にコミットするリスクを回避したい。

どのようなオプションがありますか?

55
Doug T.

昨日も同じ問題があり、次の解決策が見つかりました。 _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_キーを上書きします。私の構成では、単に黒のままにします。

50
Tammo Heeren

Alembicのドキュメント は、データベースURLでcreate_engineを使用することを推奨しています( sqlalchemy.urlをコードで変更する代わりに )。

また、新しいURLを使用するようにrun_migrations_offlineを変更する必要があります。 Allan Simonは彼のブログに を掲載していますが、要約すると、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:
        ...
    
14
danio

したがって、機能しているように見えるのは、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

確かにドキュメント ほのめかしているようです これは問題ありません:

sqlalchemy.url-SQLAlchemyを介してデータベースに接続するためのURL。このキーは、実際には「汎用」構成に固有のenv.pyファイル内でのみ参照されます。開発者がカスタマイズできるファイル。複数のデータベース構成は、ここで複数のキーに応答する場合や、ファイルの他のセクションを参照する場合があります。

9
Doug T.

ユーザー/パスのコミットを回避するために思いつくことができる最も簡単なことは、a)alembic.iniファイルに補間文字列を追加し、b)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"))

...
4
TomDotTom

しばらくの間、マルチデータベースでこれを管理する方法を探していました

これが私がしたことです。私は2つのデータベースを持っています:logsおよびohlc

doc によると、私はそのようにalembicを設定しました

alembic init --template multidb

alembic.ini

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

env.py

[...]
# 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')
[...]

config.yml

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

使用量

SETTINGS=config.yml alembic upgrade head

それが役に立てば幸い!

Doug T.が言ったように env.pyを編集して、iniファイル以外の場所からURLを提供できます。新しいエンジンを作成する代わりに、追加のurl引数をengine_from_config関数に渡すことができます(kwargsは後でiniファイルから取得したオプションにマージされます)。その場合、たとえば、暗号化されたパスワードをiniファイルに保存し、ENV変数に保存されたパスフレーズによって実行時に復号化します。

connectable = engine_from_config(                 
    config.get_section(config.config_ini_section),
    prefix='sqlalchemy.',                         
    poolclass=pool.NullPool,                      
    url=some_decrypted_endpoint)                                   
0
Bartoszer

別の解決策はテンプレートalembic.ini.distファイルを作成するで、バージョン管理されたコードで追跡し、VCSでalembic.iniを無視します。

Alembic.ini.distに機密情報を追加しないでください。

sqlalchemy.url = ...

コードをプラットフォームにデプロイするときは、alembic.ini.distをalembic.iniにコピーし(これはVCSによって追跡されません)、プラットフォームの資格情報を使用してalembic.iniを変更します。

0
rkz_io