使用 sqlalchemy/alembic 为现有数据库创建“零状态”迁移,并为现有数据库“伪造”零迁移

问题描述 投票:0回答:4

我想将 alembic 添加到现有的 sqlalchemy 使用项目,以及工作的生产数据库。我找不到执行“零”迁移的标准方法==现在设置数据库的迁移(对于设置环境的新开发人员)

目前,我已将声明性基类和使用它的所有模型添加到 env.py 中,但第一次

alembic -c alembic.dev.ini revision  --autogenerate
确实创建了现有表。

我需要使用代码“伪造”现有安装上的迁移。对于 django ORM,我知道如何做到这一点,但我找不到使用 sqlalchemy/alembic 完成此操作的正确方法

python sqlalchemy alembic
4个回答
54
投票

alembic revision --autogenerate
检查已连接数据库的状态和目标
metadata
的状态,然后创建一个迁移,使
database
metadata
保持一致。

如果您要将

alembic
/
sqlalchemy
引入到现有数据库,并且您希望迁移文件在给定空的全新数据库的情况下能够重现当前状态,请按照以下步骤操作。

  1. 确保您的

    metadata
    真正与当前的
    database
    一致(即确保运行
    alembic revision --autogenerate
    创建零操作的迁移)。确认迁移中没有任何操作后删除此文件。未能删除该文件将导致以下步骤出现
    Database is not up to date
    错误。

  2. 创建一个新的空

    temp_db
    ,并将
    sqlalchemy.url
    中的
    alembic.ini
    指向这个新的
    temp_db.

  3. 运行

    alembic revision --autogenerate
    。这将创建您所需的批量迁移,使新的数据库与当前的数据库保持一致。

  4. 删除

    temp_db
    并将
    sqlalchemy.url
    重新指向您的现有数据库。

  5. 运行

    alembic stamp head
    。这告诉 sqlalchemy 当前迁移代表数据库的状态 - 因此下次运行
    alembic upgrade head
    时,它将从此迁移开始。


16
投票

新安装:应用迁移

只需针对空数据库运行

alembic upgrade head
。 这会将所有迁移(在您的情况下,是初始迁移,因为它是唯一的)应用于数据库。

如果您想从代码而不是 shell 中执行此操作,可以按以下方式执行此操作:

from alembic.config import Config
from alembic import command
alembic_cfg = Config("/path/to/yourapp/alembic.ini")
command.upgrade(alembic_cfg, "head")

现有安装:伪造迁移

SQL方式

一种方法是针对数据库运行此 SQL:

CREATE TABLE IF NOT EXISTS alembic_version (
    version_num VARCHAR(32) NOT NULL
);

INSERT INTO alembic_version (version_num) VALUES ('your initial migration version');

第一条语句创建 alembic 用于跟踪数据库/迁移状态的表。 第二个语句基本上告诉 alembic 您的数据库状态对应于初始迁移的版本,或者换句话说,伪造迁移。

蒸馏方式

Alembic 有一个

stamp
命令,它基本上做同样的事情。 它可以从 shell 中调用为
alembic stamp head
,或者从代码中调用(取自 cookbook):

from alembic.config import Config
from alembic import command
alembic_cfg = Config("/path/to/yourapp/alembic.ini")
command.stamp(alembic_cfg, "head")

1
投票

我遵循的路径与 michael_j_ward 略有不同,它不需要创建空数据库。对于我正在处理的项目,数据库中有不同的架构,对于此应用程序,数据位于单独的架构中。在 alembic 中,您可以通过在

env.py
文件中定义 include_name 函数来指定应在哪个 schema alembic 上执行操作:

def include_name(name, type_, parent_names):
    if type_ == "schema":
        return name == "your_schema"
    else:
        return True

通过将架构设置为不存在的值,它会在迁移中从头开始生成所有表和列(因为还没有任何内容)。

之后,在 include_name 函数中切换回原始模式。

使用特定模式时,run_migrations_online 方法中的配置参数如下所示

        context.configure(
            connection=connection,
            include_schemas=True,
            include_name=include_name,
            target_metadata=get_metadata(),
            version_table_schema="your_schema", # alembic_version table is created in this schema
            **conf_args
        )

0
投票

为现有数据库生成模型

您可以使用 sqlacodegen 通过对现有数据库的内省来创建模型。

如果您已经有 sqlalchemy 模型,请将生成的模型与您的模型进行比较并进行相应调整。

然后您可以运行

alembic revision --autogenerate
来创建初始迁移。

为了确保您的 sqlalchemy 模型将创建与原始数据库相同的架构,您可以使用 liquibaseflywaybytebase 等工具来比较原始架构与 sqlachemy/alembic 生成的架构的差异。

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