【问题标题】:Flask-SQLAlchemy integration test clear database after each test with foreign key constraintsFlask-SQLAlchemy 集成测试在每次使用外键约束的测试后清除数据库
【发布时间】:2021-12-11 01:42:59
【问题描述】:

我想知道如何使用flask-sqlalchemyunittest 编写快速集成测试,而无需在每个测试中创建和删除表。我使用 Postgres 作为我的数据库。

现在,表分别在setUpClasstearDownClass 中创建和删除,从性能的角度来看这很好。我需要的是一种在每个单独的测试中删除所有数据并“重置”数据库的方法,而无需重新创建所有表。

我得到的最接近的是这段代码,但由于外键限制,它引发了IntegrityError

def tearDown(self):
    meta = db.metadata
    for table in reversed(meta.sorted_tables):
        db.session.execute(table.delete())

    db.session.commit()

重要提示:由于我正在进行集成测试,我不可避免地会在我的应用程序代码中点击db.session.commit,这会使任何会话事务无效,因此我无法将其用作解决方案。

【问题讨论】:

  • 您能否使用内存数据库,例如 H2 (h2database.com/html/main.html) 进行测试?它不一定与 postgres 完全兼容,但如果您只使用基本功能,它就足够了。如果没有,那么我建议您以确保没有冲突的方式编写测试。您可以在每次运行测试套件时生成唯一密钥,也可以在所有测试运行后清除数据库一次

标签: python sqlalchemy flask-sqlalchemy python-unittest


【解决方案1】:

试试这个:

for table in reversed(meta.sorted_tables):
    db.session.execute(f"TRUNCATE {table.name} RESTART IDENTITY CASCADE;")

CASCADE 在这里成功了,来自postgres docs

Automatically truncate all tables that have foreign-key references to any of the named tables, or to any tables added to the group due to CASCADE.

所以它告诉 postgres 删除所有指向截断表中的行的行。

另一方面,RESTART IDENTITY:

Automatically restart sequences owned by columns of the truncated table(s).

使您的自动增量列从头开始。

【讨论】:

  • 不错,这行得通!您是否介意在您的回答中添加一点解释 RESTART IDENTITY CASCADE 的作用?
  • @DariusCosden 添加了一点解释,希望对您有所帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-24
  • 2020-11-02
  • 1970-01-01
  • 2020-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多