python - 覆盖 alembic env.py 文件中的值

标签 python pytest alembic

我正在使用 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

这样效果很好。

关于python - 覆盖 alembic env.py 文件中的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71279609/

相关文章:

alembic - 使用 flask-migrate 时如何为 alembic_version 指定表模式

python - 更改现有 Django 项目的时区

python - 如何参数化测试以在 pytest 中使用不同的装置运行?

python - 将数据库迁移从 sqlalchemy-migrate 更改为 Flask-Migrate

python - py.test 测试 flask 寄存器,AssertionError : Popped wrong request context

python - 重新引发异常时如何避免在 pytest 中显示原始异常?

python - 如何清除历史记录并从头开始运行所有迁移?

python - 如何像 Freebase 一样存储数据?

python - 运行 django-admin.py startproject 给我一个错误

python - Django 管理屏幕不按名称显示实体