首页 > 解决方案 > 模型导入和测试中的 Alembic 模式升级之间的 SQLAlchemy 元数据冲突

问题描述

我有一个带有 PostgreSQL 数据库、Alembic 迁移和 SQLAlchemy 的 Flask 应用程序。

最近我开始编写针对数据库的集成测试。我导入了一个模型,比如项目,它映射到表“项目”,并且执行“从模型导入项目”触发为我的表构建 SQLAlchemy 元数据。

在我的测试设置中,我有

    def setUpClass(cls):
        try:
            os.remove('testdb.db:')
        except:
            pass

        #Run db migrations
        global db_manager

        db_manager = DatabaseManager()
        alembic_cfg = Config("./alembic.ini")
        alembic_cfg.attributes['db_manager'] = db_manager
        command.upgrade(alembic_cfg, "head")

这导致

sqlalchemy.exc.InvalidRequestError:已经为此 MetaData 实例定义了表“项目”。指定 'extend_existing=True' 以重新定义现有 Table 对象上的选项和列。

我已将其调试为元数据对象在调用之间是相同的,因此将“项目”表两次累积到其表数组中。

我有另一个几乎相同的应用程序,这个设置可以工作,所以我知道它应该在理论上工作。在这个其他应用程序中,导入和升级阶段的元数据对象不同,因此当 alembic 运行升级时表数组为空,因此没有错误。

抱歉,我无法提供实际代码,工作项目。如果我有时间,也许可以构建一个最小的玩具示例。

如果我了解在 SQLAlchemy 中实际创建元数据的位置,我可能能够追踪为什么 alembic 在工作应用程序中获得一个干净的元数据实例,而不是在问题应用程序中。

在工作应用程序中,未设置“extend_existing”,我宁愿不调用一些黑客来掩盖潜在问题。

标签: pythonsqlalchemyalembic

解决方案


推荐阅读