覆盖 alembic env.py 文件中的值
Override values in alembic env.py file
我正在使用 alembic 进行数据库修订,这可能与预期的差不多。我没有在 alembic.ini
中定义数据库字符串,而是使用 env.py
文件从配置模块动态获取数据库凭据,大致如下:
SQLALCHEMY_DATABASE_URL = "%s://%s:%s@%s:%d/%s" % (settings.db_type, settings.db_username, settings.db_password, settings.db_host, settings.db_port, settings.db_database)
def run_migrations_online():
"""Run migrations in 'online' mode.
In this scenario we need to create an Engine
and associate a connection with the context.
"""
connectable = create_engine(SQLALCHEMY_DATABASE_URL)
with connectable.connect() as connection:
context.configure(
connection=connection, target_metadata=target_metadata
)
with context.begin_transaction():
context.run_migrations()
现在的问题是我正在添加 pytest 测试,这些测试使用单独的数据库连接。基本上我正在做的是创建一个数据库,应用迁移,添加测试数据,运行 测试,删除数据库。
在 pytest 中,我按如下方式使用它:
@pytest.fixture(scope="session")
def initialize_database(create_database):
"""
Executes all alembic versions against the empty database to get the general structure up and running.
No need to yield / delete as the entire database is deleted anyway as part of the `create_database` yield fixture
"""
# retrieves the directory that *this* file is in
root_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
# this assumes the alembic.ini is also contained in this same directory
config_file = os.path.join(root_dir, "alembic.ini")
migrations_dir = os.path.join(root_dir, "alembic")
config = Config(file_=config_file)
config.set_main_option("script_location", migrations_dir)
command.upgrade(config, 'head')
我试图在此处指定不同的数据库凭据,但 env.py
中的值覆盖了它。如何在这样的设置中指定不同的数据库凭据?
我自己找到了解决办法,其实很简单。从测试夹具调用 upgrade
命令时,我设置了两个额外的配置值,如下所示:
config.set_main_option("is_testing", "True")
config.set_main_option('sqlalchemy.url', SQLALCHEMY_DATABASE_URL)
在 env.py
文件中,我可以使用此测试选项动态更改 SQLAlchemy url,如下所示:
SQLALCHEMY_DATABASE_URL = "%s://%s:%s@%s:%d/%s" % (settings.db_type, settings.db_username, settings.db_password, settings.db_host, settings.db_port, settings.db_database)
if config.get_main_option("is_testing", "False") == "True":
url = config.get_main_option("sqlalchemy.url")
else:
url = SQLALCHEMY_DATABASE_URL
这样效果很好。
我正在使用 alembic 进行数据库修订,这可能与预期的差不多。我没有在 alembic.ini
中定义数据库字符串,而是使用 env.py
文件从配置模块动态获取数据库凭据,大致如下:
SQLALCHEMY_DATABASE_URL = "%s://%s:%s@%s:%d/%s" % (settings.db_type, settings.db_username, settings.db_password, settings.db_host, settings.db_port, settings.db_database)
def run_migrations_online():
"""Run migrations in 'online' mode.
In this scenario we need to create an Engine
and associate a connection with the context.
"""
connectable = create_engine(SQLALCHEMY_DATABASE_URL)
with connectable.connect() as connection:
context.configure(
connection=connection, target_metadata=target_metadata
)
with context.begin_transaction():
context.run_migrations()
现在的问题是我正在添加 pytest 测试,这些测试使用单独的数据库连接。基本上我正在做的是创建一个数据库,应用迁移,添加测试数据,运行 测试,删除数据库。
在 pytest 中,我按如下方式使用它:
@pytest.fixture(scope="session")
def initialize_database(create_database):
"""
Executes all alembic versions against the empty database to get the general structure up and running.
No need to yield / delete as the entire database is deleted anyway as part of the `create_database` yield fixture
"""
# retrieves the directory that *this* file is in
root_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
# this assumes the alembic.ini is also contained in this same directory
config_file = os.path.join(root_dir, "alembic.ini")
migrations_dir = os.path.join(root_dir, "alembic")
config = Config(file_=config_file)
config.set_main_option("script_location", migrations_dir)
command.upgrade(config, 'head')
我试图在此处指定不同的数据库凭据,但 env.py
中的值覆盖了它。如何在这样的设置中指定不同的数据库凭据?
我自己找到了解决办法,其实很简单。从测试夹具调用 upgrade
命令时,我设置了两个额外的配置值,如下所示:
config.set_main_option("is_testing", "True")
config.set_main_option('sqlalchemy.url', SQLALCHEMY_DATABASE_URL)
在 env.py
文件中,我可以使用此测试选项动态更改 SQLAlchemy url,如下所示:
SQLALCHEMY_DATABASE_URL = "%s://%s:%s@%s:%d/%s" % (settings.db_type, settings.db_username, settings.db_password, settings.db_host, settings.db_port, settings.db_database)
if config.get_main_option("is_testing", "False") == "True":
url = config.get_main_option("sqlalchemy.url")
else:
url = SQLALCHEMY_DATABASE_URL
这样效果很好。