You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为notification_delay添加default参数为何影响CheckConstraint测试?

active = db.Column(db.Boolean, nullable=False, default=True)
deleted = db.Column(db.Boolean, nullable=False, default=False)
notification_delay = db.Column(db.Integer, nullable=False)
...
__table_args__ = (db.CheckConstraint("NOT (deleted = 1 AND active = 1)", name="check_active_when_deleted"),)
### 测试用例
```python
def test_deleted_when_active(self, db):
    with pytest.raises(IntegrityError):
        a = Alarm(
            condition=TimeoutCondition(
                property_uuid='d891ef94-5775-440c-9ede-be423b3e70ae',
                timeout_sec=15 * 60
            ),
            alarmtype=AlarmType.by_code('timeout'),
            deleted=True
        )
        db.session.add(a)
        db.session.commit()

异常现象

该测试原本可正常触发IntegrityError,但为notification_delay字段添加default=0参数后,测试不再抛出该异常导致失败;移除异常捕获语句后,测试可正常通过。


原因解析

1. 初始测试的异常并非来自目标约束

在未给notification_delay添加default=0时,该字段无默认值且强制非空。创建Alarm实例时未传入该字段值,提交会话时会先触发非空约束的IntegrityError,此时数据库还未执行到check_active_when_deleted约束的检查。测试用例捕获到IntegrityError,误判为触发了删除与激活状态的冲突约束,但实际和目标约束无关。

2. 添加默认值后目标约束未生效

给notification_delay添加default=0后,非空约束不再触发,此时active使用默认值True、deleted被设为True,本该触发check_active_when_deleted约束,但测试未抛出异常,核心原因是该自定义约束未在数据库中实际生效,常见场景包括:

  • 模型修改后未执行数据库迁移,数据库表中并未创建这个check约束;
  • 使用的数据库(如SQLite)默认忽略check约束,需额外配置(如SQLAlchemy中设置sqlite_enforce_check_constraints=True)才能启用;
  • ORM层面的默认值与数据库层面的默认值未同步,导致插入时数据库未识别到冲突状态。

内容的提问来源于stack exchange,提问作者Jan-Pieter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 06:40:35