通过约束对数据库中的验证逻辑进行建模.好主意,坏主意,还是不值得?



当数据库中不存在这些相同的约束时,在模型的clean方法中编写代码以验证数据的各种约束总是让我感到困惑。

毕竟,数据库已经对我的某些数据有约束,例如 NOT NULL。

因此,我一直在编写 RawSQL 迁移,这些迁移ADD CONSTRAINT some_logic我最近的项目中,与我在clean()方法中的任何逻辑相匹配。

它工作正常,但记住添加这些约束、为这些迁移添加测试并在模型更改时更新它们并不是一项微不足道的任务。 另外,当然,我在两个地方编写代码来做同样的事情违反了 DRY。

我应该放弃这个堂吉诃德式的追求吗?

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

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

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

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

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

如果在clean()中编写太多逻辑感觉很脏,那么介于两者之间的解决方案是直接在模型字段上使用 Django 的内置验证器。

验证逻辑不会保存在数据库中,但在迁移中会进行跟踪。像clean()逻辑一样,验证器要求您调用Model.clean_fields(),但ModelForm会自动执行此操作。

你也可以深入研究django-db-constraints。该库可能有助于完成您想要执行的操作,源代码可能会帮助您推出适合您需求的解决方案。

最新更新