通过约束在数据库中建模验证逻辑。好主意,坏主意或不值得吗?

时间:2018-05-03 00:12:36

标签: sql django database

在我的模型的clean方法中编写代码时,总是以错误的方式揉搓我以验证数据的各种约束,当这些相同的约束也不存在于数据库中。

毕竟,数据库已经存在某些数据的约束,比如NOT NULL。

所以,我在我最近的项目中编写了ADD CONSTRAINT some_logic的RawSQL迁移,它与我clean()方法中的逻辑相匹配。

它运行正常,但要记住添加这些约束,为这些迁移添加测试并在模型更改时更新它们并不是一项无关紧要的任务。当然,我通过在两个地方编写代码来做同样的事情来侵犯DRY。

我应该放弃这个不切实际的任务吗?

2 个答案:

答案 0 :(得分:2)

这绝不是一个全面的答案,但至少我想表达我的意见。

有许多框架推动了从数据库中删除约束的想法,以便在应用程序级别检查它们。这个想法最初对我来说很好(在21世纪初),但经过几年的努力,我得出了(非常个人的)结论,这是一个坏主意。

我认为,对我来说,归结为两件事:

  • 数据存活的时间比应用程序长得多。整个系统已经过时,但数据还存活了很多年。有时应用程序被替换,但数据库仍然是相同的。
  • 在验证数据时,应用程序不可靠。我在这里谈论编程缺陷。一个版本的应用程序可能运行良好,然后下一个版本有一个错误。可能是一个开发人员离开公司,然后新的替代者 - 谁也不知道 - 改变了应用程序带来的灾难性后果。一直以来,简单的数据库约束(实现起来通常非常便宜)都可以强制实施数据质量。

是的,我是严格数据库约束的粉丝。然而,这并不意味着我反对应用程序验证。这些可以显示更好的错误消息。

答案 1 :(得分:2)

如果在clean()中写入太多逻辑感觉很脏,则中间解决方案是直接在模型字段上使用Django's built-in validators

验证逻辑未保存在数据库中,但会在迁移中进行跟踪。与clean()逻辑类似,Validators要求您拨打Model.clean_fields(),但ModelForm会自动执行此操作。

您还可以深入了解django-db-constraints。该库可能有助于完成您想要做的事情,源代码可以帮助您推出符合您需求的解决方案。