0

session.merge在 SqlAlchemy 中使用 向表中插入数据UniqueConstraint,这对于多个列来说很常见,例如,我的 ORM 类具有以下内容:

UniqueConstraint("attr_1", "attr_2", "attr_3", name="attributes_uix")

我应该使用filter还是filter_bywith_and来检查我要插入的数据是否会违反这个唯一约束,或者它是IntegrityError通过try - except构造捕获的正确方法吗?

4

1 回答 1

2

没有 sql-alchemy 专家,但已经为这个和类似的问题苦苦挣扎了一段时间。我不确定在这种情况下是否有一个正确的方法。我可以为您描述的是在获取数据库异常和在代码中处理它之间的权衡是什么。

我个人更喜欢捕获数据库异常。这具有不运行额外查询(具有额外延迟等)的优势。它还具有尽可能重用现有框架部分的优势。

然而,它有两个真正的缺点。第一个可以在 db 设计级别解决,即包含 NULL 值的匹配不会违反多列唯一约束。换句话说,如果我在 (id, value) 上有一个 cnstraint,则(1, null), (1, null)不能说是非唯一的,因此不会抛出完整性异常。所以首先值得检查一下是否可以避免这个问题。如果没有,您需要找到一种解决方法,但 PostgreSQL 为您提供了很多工具(例如,功能索引)。

第二个是捕获 IntegrityError 是一种钝器,您无法真正解析任何可用于索引名称的错误消息,因为这可能因系统而异,并且区域设置可能意味着该消息可能被翻译。所以你依赖于 SQLSTATE,这不是很精确。即您没有良好的机器可读信息。如果有多个候选人,则违反了哪个约束。

那么问题就在这些与重复代码和查询之间。通常我认为捕捉错误是较小的邪恶,但由于权衡,它不是一个普遍的建议。

于 2015-11-02T04:47:56.013 回答