将alembic与多个数据库结合使用

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

我有一个非常标准的烧瓶应用程序。它使用

flask_sqlalchemy
管理与
postgres
服务器的连接,并使用
alembic
管理迁移。

现在的问题是我正在将它与另一个项目集成,这意味着我试图允许它从另一个数据库中提取单个模型。幸运的是,

flask_sqlalchemy
通过
SQLALCHEMY_BINDS
标志对此提供了大力支持。所以我的应用程序设置了一个新模型,如下所示:

class CoreUser(UserMixin, db.Model):
    __bind_key__ = 'core'

    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(255), unique=True)

到目前为止一切顺利。我的应用程序现在在应该时检查另一个数据库。但这是缺点。由于我使用

alembic
来实际管理数据库中的所有模式,因此当我运行典型的
alembic revision --autogenerate
脚本时,它实际上根本不会对第二个数据库执行任何操作,并且似乎只是忽略了
 __bind_key__
拼图的一部分。

相反,它在第一个数据库中设置正确的

core_user
关系。我如何向 alembic 表明,当它遇到此模式定义时,它应该在不同的数据库中创建关系?

我已经尝试根据

this
(古代)线程的建议更新我的alembic.ini文件,如下所示:

[core_db]
sqlalchemy.url = <DATABASE_URI>
script_location = alembic

然后运行以下命令:

alembic -n core_db revision --autogenerate
alembic -n core_db upgrade head

虽然生成了修订版本并且不会失败,但在数据库中实际没有创建由

core_db
sqlalchemy.url
参数指示的关系。

我找不到比 4 年前的 Google 小组帖子更好的文档,但我目前的方法似乎不起作用,而且我没有任何明显的后续步骤。我无法找到适当的

alembic
文档,但这似乎是一个非常简单且常见的用例,所以我无法想象这不受支持。

有什么建议吗?

python postgresql flask flask-sqlalchemy alembic
4个回答
4
投票

很难处理许多数据库不同模型的迁移。

在我们的例子中,我们有 N 个具有不同模型的数据库。以下结构有助于保持数据库隔离:

.
├── app
│   ├── __init__.py
│   ├── alembic.ini
│   ├── employee
│   │   ├── __init__.py
│   │   ├── models.py
│   │   └── views.py
│   ├── migrations
│   └── user
│       ├── __init__.py
│       ├── models.py
│       └── views.py
├── daemon
│   ├── __init__.py
│   ├── alembic.ini
│   ├── daemon_engine.py
│   ├── migrations
│   └── models.py
├── run.py
└── tests

2
投票

您到目前为止所采取的步骤是正确的。

但是,您是否为每个数据库在

target_metadata
中分配了正确的
env.py

如果传入的元数据对于两个数据库相同,则不会找到不同的关系,因此自动生成的脚本将不会反映您正在查找的内容。

通过查看

Base.metadata.tables
变量来检查哪些表与元数据关联。

仅传入每个数据库所需的表

env.py
。每个数据库都应该在各自的
script_location
中拥有一个。


1
投票

我通过使用

flask-sqlalchemy
及其
alembic
选项,使其与
flask-migrate
--multidb
一起使用:

https://flask-migrate.readthedocs.io/en/latest/#multiple-database-support

然后我必须修改所有旧的数据库迁移(当我只有一个数据库时),如此处所述:

https://github.com/miguelgrinberg/Flask-Migrate/issues/181

升级脚本仍然遇到一些麻烦,因为它向这个新数据库添加和删除了我的所有旧表。不确定那是什么,但很快就会知道...


0
投票

这很难。使用自动生成功能创建新修订版时,Alembic(从

v1.11.3
开始)通过将ONLY连接到版本表的单个数据库来检查历史记录,并通过访问文件夹中的所有脚本文件来提取所有头
 migrations/versions
(假设只有一个版本路径)。

换句话说,Alembic 始终假设每个迁移文件夹只有一个数据库。将第二次(或后续)迁移升级到其中一个数据库时,您将收到错误

对于那些对实现细节感兴趣的人,请查看以下功能:

  • MigrationContext.get_current_heads()
    here,Alembic 验证数据库中的最后提交历史记录。
  • RevisionContext._run_environment()
    here,Alembic加载所有头/分支的脚本,并与上面操作的结果进行比较。
© www.soinside.com 2019 - 2024. All rights reserved.