在我开始工作之前,我遇到了几个必须解决的问题。
最初,Alembic 根本没有看到我的数据库。如果我试图在 alembic.ini 文件中指定它,它将使用默认模式加载 SQLite 数据库,但我的模型代码指定了一个模式,所以这不起作用。我不得不更改alembic/env.py以run_migrations_online()从我的代码中调用我的连接方法,而不是使用engine_from_config. 在我的例子中,我创建了一个数据库对象,它有一个connect()方法可以返回engine和metadata. 我称之为connectable, meta = db.connect(). 我会用schema=db.schema(). 我必须从我的 SQLAlchemy 代码中导入db该类才能访问这些。
现在我得到了一个从头开始构建整个数据库的迁移,但我无法运行该迁移,因为我的数据库已经有了这些更改。显然,Alembic 没有看到我的数据库。Alembic 还不断告诉我我的数据库已经过时了。问题在于,alembic 表alembic_version正在写入我的:memory:数据库,并且一旦连接断开,数据库也是如此。所以为了让 Alembic 记住迁移,我需要在我的数据库中创建该表。我添加了更多代码以env.py将架构传递给context.configure使用version_table_schema=my_schema.
当我再次生成迁移时,我仍然得到了从头开始构建数据库的迁移,所以 Alembic 仍然没有看到我的数据库。经过更多的谷歌搜索,我发现我需要传递include_schemas=True给context.configurein env.py。但在我添加之后,我开始从 Alembic 获得回溯。
幸运的是,我的配置设置为同时提供连接和元数据。通过将target_metadata=target_metadata行更改为target_metadata=meta(从连接返回的本地元数据),我也绕过了这些回溯,并且 Alembic 开始正常运行。
回顾一下,为了让 Alembic 使用附加为模式名称的 SQLite 数据库,我必须导入用于 Flask 代码的连接脚本。该连接脚本正确附加 SQLite 数据库,然后反映元数据。它返回引擎和元数据。我将引擎返回到 env.py 中的“可连接”变量,并将元数据返回到新的局部变量 meta。我还将模式名称返回给局部变量模式。
在 with connectable.connect() as connection: 块中,然后我传递给 context.configure 附加参数target_metadata=meta, version_table_schema=schema,include_schemas=True其中 meta 和 schema 是我在上面设置的新局部变量。
通过所有这些更改,我认为我能够使用作为模式附加的 SQLite 数据库。不幸的是,我继续遇到问题,并最终决定我根本不会使用带有 Alembic 的 SQLite。我们现在的规则是 Alembic 迁移仅适用于非 SQLite 数据库,并且在尝试对数据进行 Alembic 迁移之前,必须将 SQLite 数据迁移到另一个数据库。
我正在记录这一点,以便面临此问题的其他任何人都可以遵循我所做的事情,并可能让 Alembic 为 SQLite 工作。