我的django模型看起来像这样:
class Entity(models.Model):
name = models.CharField(max_length=40)
examples = models.ManyToManyField(Example, blank=True)
tokens = models.ManyToManyField(Token, blank=True, null=True)
我想在令牌中强制执行唯一性,即如果已经有一个带有令牌的实体['a','b','c']我不想添加另一个带有''a','b的实体', 'C']。但是,具有令牌['a','b','c','d']或['a','b']的实体是一个不同的集合,应该添加。
如果已找到具有特定集的实体,我想将已发现的新示例添加到ManyToMany。旧名称可以保留。
目前,我运行一个查询来获取一个有问题的精确令牌集的现有实体(这本身就是django中的一个挑战),然后如果找到它我用新的例子更新它。问题是它在多个服务器上运行多个进程,因此在检查匹配的实体是否存在与创建新实体(如果找不到)之间存在竞争条件。这可能会导致创建具有重复令牌集的实体。
我提出的一个解决方案是为ManyToMany使用显式直通模型,并覆盖直通模型的save方法以创建令牌集的哈希值,并将其包含在直通模型本身的列上。独特的约束。我认为这会起作用,但它似乎不是一个特别优雅的解决方案。
我还想象在你需要一个独特的集合的情况下,这个问题在带有映射表的SQL领域中有点普遍 - 也许这里有一个众所周知的解决方案?我当然愿意使用原始sql。
提前感谢您的帮助!
答案 0 :(得分:2)
我不完全确定这种方法能解决你的问题,但现在就去了。
与 Big 保险公司数据库合作的朋友正在寻找一种基于列子集快速检测多个数据库中确切欺骗的方法。我建议使用他正在检查的列集,通过某种canonicalifier™运行它们,计算MD5摘要,并将其保存为表的附加索引列。傻逼像闪电一样。
所以也许你可以做类似的事情。它没有解决你的竞争条件(我无法想到的事情),但它可以大大简化欺骗检查。