Можно ли сохранить строку alembic connect за пределами alembic.ini?
Я использую Alembic с SQL Alchemy. В SQL Alchemy я склонен следовать шаблону, в котором я не сохраняю строку подключения с версионным кодом. Вместо этого у меня есть файл secret.py
который содержит любую конфиденциальную информацию. Я .gitignore
это имя файла в мой .gitignore
чтобы он не .gitignore
на GitHub.
Этот шаблон работает нормально, но теперь я использую Alembic для миграции. Похоже, я не могу скрыть строку подключения. Вместо этого в alembic.ini вы помещаете строку подключения в качестве параметра конфигурации:
# the 'revision' command, regardless of autogenerate
# revision_environment = false
sqlalchemy.url = driver://user:[email protected]/dbname
# Logging configuration
[loggers]
keys = root,sqlalchemy,alembi
Я боюсь, что я собираюсь случайно зафиксировать файл с именем пользователя/паролем для моей базы данных. Я бы предпочел хранить эту строку подключения в одном месте и избежать риска случайной фиксации ее для контроля версий.
Какие варианты у меня есть?
Ответы
Ответ 1
У меня вчера была та же самая проблема, и я нашел следующее решение для работы. Я делаю следующее в 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
файла. В моей конфигурации я просто оставляю это черным.
Ответ 2
В документации Alembic предлагается использовать create_engine
с URL-адресом базы данных (вместо изменения sqlalchemy.url в коде).
Также вы должны изменить run_migrations_offline, чтобы использовать новый URL. У Аллана Саймона есть пример в его блоге, но в итоге измените env.py так:
-
Предоставьте разделяемую функцию для получения 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
-
Используйте URL в автономном режиме:
def run_migrations_offline():
...
url = get_url()
context.configure(
url=url, target_metadata=target_metadata, literal_binds=True)
...
-
Используйте URL в режиме онлайн, используя create_engine
вместо engine_from_config
:
def run_migrations_online():
...
connectable = create_engine(get_url())
with connectable.connect() as connection:
...
Ответ 3
Итак, что работает, это переопределение создания движка в env.py, что, по-видимому, является местом для такого рода настройки Вместо того, чтобы использовать строку подключения sqlalchemy в ini:
engine = engine_from_config(
config.get_section(config.config_ini_section),
prefix='sqlalchemy.',
poolclass=pool.NullPool)
Вы можете заменить и указать свою собственную конфигурацию двигателя:
import store
engine = store.engine
Действительно, docs подразумевает, это нормально:
sqlalchemy.url - URL-адрес для подключения к базе данных через SQLAlchemy. Этот ключ фактически ссылается только в файле env.py, который специфичен для "общей" конфигурации; файл, который может быть настроен разработчиком. Конфигурация нескольких баз данных может отвечать на несколько ключей здесь или может ссылаться на другие разделы файла.
Ответ 4
Другим решением является создать шаблон файла alembic.ini.dist и отслеживать его с помощью кода с версией, игнорируя alembic.ini в вашем VCS.
Не добавляйте конфиденциальную информацию в файл alembic.ini.dist:
sqlalchemy.url = ...
При развертывании вашего кода на платформе скопируйте файл alembic.ini.dist в alembic.ini(этот не будет отслеживаться вашим VCS) и измените alembic.ini с учетными данными платформы.
Ответ 5
Как сказал Doug T., вы можете редактировать env.py, чтобы указать URL-адрес из другого места, кроме ini файла. Вместо создания нового движка вы можете передать дополнительный аргумент 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)
Ответ 6
Я ответил здесь, как обрабатывается с конфигурационным файлом и мульти-базой данных
Ответ 7
Я искал какое-то время, как управлять этим для mutli-баз данных
Вот что я сделал. У меня есть две базы данных: журналы и ohlc
Согласно документу, я настроил Alembic таким образом
alembic init --template multidb
alembic.ini
databases = logs, ohlc
[logs]
sqlalchemy.url = postgresql://botcrypto:[email protected]/logs
[ohlc]
sqlalchemy.url = postgresql://botcrypto:[email protected]/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
Надеюсь, что это может помочь!