Python 避免向Django模型添加重复项的有效方法
我已经阅读了很多关于如何在Django中使数据库/模型独一无二的文章,这些似乎都很有效。然而,我没有看到任何帖子讨论避免向数据库添加重复条目的有效方法 我的模型如下所示:Python 避免向Django模型添加重复项的有效方法,python,django,Python,Django,我已经阅读了很多关于如何在Django中使数据库/模型独一无二的文章,这些似乎都很有效。然而,我没有看到任何帖子讨论避免向数据库添加重复条目的有效方法 我的模型如下所示: # from app.models class TestModel(models.Model): text = models.TextField(unique=True, null=True) fixed_field = models.TextField() 我目前避免添加重复条目而不出错的方法如下 # fr
# from app.models
class TestModel(models.Model):
text = models.TextField(unique=True, null=True)
fixed_field = models.TextField()
我目前避免添加重复条目而不出错的方法如下
# from app.views
posts = ["one", "two", "three"]
fixed_field = "test"
for post in posts:
try:
TestModel(text=post, fixed_field = fixed_field).save()
except IntegrityError:
pass
如果我不这样做,我会得到一个完整的错误。有什么方法可以提高效率吗?如果要批量添加项目,可以先获取需要唯一的文本,然后列出不引入重复项的
TestModel
:
used_text = set(TestModel.objects.values_list('text', flat=True))
posts = ['one', 'two', 'three']
fixed_field = "test"
test_models = []
for post in posts:
if post not in used_text:
used_text.add(post)
test_models.add(TestModel(text=post, fixed_field = fixed_field))
test_models.objects.bulk_create(test_models)
然后,通常在一个查询中批量创建所有记录。如果多个查询中的元素数量很大,但每个查询都会插入大量记录
但是,由于竞争条件,上述操作仍然可能失败,因为在获取数据库中的
文本
和添加新文本之间,其他查询可以更新数据库的状态,因此,尽管可能性不大,但您可能应该使用重试机制,再次从列表中筛选出TestModel
s,并尝试重新插入这些内容。非常感谢您的回复。就我自己的直觉而言,我目前的解决方案是“种族条件证明”,对吗?尽管我可以想象它比正确实现某种重试机制要慢。@MennoVanDijk:如果数据库是竞争条件证明,则是:),尽管如果要插入大量项(1000+),这将需要一些时间,因为每次都要往返数据库。如果数据库没有经常修改(因此不太可能发生冲突),那么通常批量插入会更快。当然,如果并发插入的数量非常高,那么最终可能是您一直在尝试插入,但每次都失败了。好吧,对于webdev来说是非常新的,所以仍然在寻找最佳实践方法来解决类似这些琐碎的问题。谢谢你的建议,我会看看是否能在适当的时候找到合适的解决办法。