数据约束

Odoo 为什么有些约束要写到数据库层:_sql_constraints 和 Python constraints 边界讲透

很多数据校验问题,看起来都能用 Python 写,但真正要守住数据底线时,数据库层约束和模型层约束并不是同一回事。本文把边界讲清楚。

Odoo 开发
进阶 开发者 1 分钟阅读
0 评论 0 点赞 0 收藏 6 阅读

先说结论

在 Odoo 里,很多人会把所有数据校验都想成“在 Python 里拦一下就行”。

但真正要理解清楚的是:

  • _sql_constraints
  • Python constraints

这两类约束虽然都在保护数据,却站在完全不同的边界层上。

最实用的理解是:

Python 约束更像业务层判断,SQL 约束更像数据库底线保护。


为什么这两个特别容易被混

因为它们表面都在做一件事:

  • 不让坏数据进来

所以很多人会觉得:

  • 既然 Python 能写,为什么还要数据库层?

但问题在于,系统真正需要的不只是“提示用户”,还包括:

  • 数据在任何入口、任何并发情况下都不能突破的底线

这时数据库层和模型层就不是同一层责任了。


Python constraints 更像什么

它更像:

模型语义层的业务校验。

它特别适合:

  • 跨字段业务逻辑判断
  • 读起来更像业务规则的限制
  • 需要更灵活表达的条件判断

所以它很适合表达“业务上不合理”。


_sql_constraints 更像什么

它更像:

数据库层不可突破的数据底线。

它特别适合:

  • 唯一性
  • 基础数值合法性
  • 某些无论哪个入口都绝不能违反的硬约束

所以它的意义不只是“再写一遍规则”,而是把底线压到最靠近数据的那层去守。


为什么“能在 Python 里拦住”还不够

因为数据进入系统的入口不止一种:

  • 表单
  • 导入
  • 自动化
  • API
  • 并发写入

如果你只在模型层或某条调用路径里拦,仍然可能留下边界缝隙。

这也是为什么真正涉及数据底线时,数据库层约束特别值钱。


为什么这不是“谁更高级”的问题

不是说 _sql_constraints 一定比 Python 约束高级,或反过来更灵活就更好。

更准确的理解是:

  • 你到底想守的是业务语义
  • 还是数据库绝不能破的底线

很多时候,两层都要有,但职责不同。

所以关键不是二选一,而是:

  • 该把哪类规则放在哪一层。

实战里最容易踩的 5 个坑

1. 把所有规则都只写在 Python 层

底层完整性保护会不够硬。

2. 把复杂业务语义硬塞进 SQL 约束

可维护性会变差。

3. 以为两者只是写法不同

会低估边界层次差异。

4. 忽视并发和多入口写入场景

问题上线后才暴露。

5. 不先区分“业务不合理”和“数据绝不能存在”

规则设计会混乱。


一句话记忆法

把它记成一句话:

Python constraints 更像业务语义校验,_sql_constraints 更像数据库层底线保护;两者都在约束数据,但守的是不同层的边界。

理解这一句,数据约束设计会稳很多。

DISCUSSION

评论区

想参与讨论?先 登录 再发表评论。
还没有评论,你可以成为第一个留言的人。