Python 如何使用Django ORM执行大容量插入或增量类型操作
我有一个定义如下的模型:Python 如何使用Django ORM执行大容量插入或增量类型操作,python,django,postgresql,Python,Django,Postgresql,我有一个定义如下的模型: class VectorSet(models.Model): word = models.CharField(max_length=255) weight = models.IntegerField() session = models.ForeignKey(ResearchSession) 我想写一个函数,它将获取一个单词列表和一个研究会话,对于该单词列表中的每个单词,如果它不存在,则创建一个权重为1的新行,否则,获取该行并将权重增加1 到目
class VectorSet(models.Model):
word = models.CharField(max_length=255)
weight = models.IntegerField()
session = models.ForeignKey(ResearchSession)
我想写一个函数,它将获取一个单词列表和一个研究会话,对于该单词列表中的每个单词,如果它不存在,则创建一个权重为1的新行,否则,获取该行并将权重增加1
到目前为止,我已经了解到:
def train(words, session):
for i in words:
result, created = VectorSet.objects.get_or_create(word=i, session=session,
defaults={'weight' : 1})
if not created:
result.weight = F('weight') + 1
result.save()
我很有信心,有一种方法可以通过一个查询实现这一点,但是我不太清楚这可能是什么,或者是否可以通过原始SQL使用django代码。除了我认为的以外,目前没有现成的解决方案来进行批量插入。另一种解决方案(取决于您的数据库)是使用在事务中执行get_或_create。例如:
from django.db import transaction
@transaction.atomic
def train(words, session):
for i in words:
result, created = VectorSet.objects.get_or_create(word=i, session=session,
defaults={'weight' : 1})
if not created:
result.weight = F('weight') + 1
result.save()
否则,您可能可以使用DB API:
逻辑很简单,但我们需要多次点击DB,这意味着需要多次查询:
qs = VectorSet.objects.filter(word__in=words, session=session)
qs.update(weiget=models.F('weight')+1)
VectorSet.objects.bulk_insert(VectorSet(session=session, word=w, weight=1)
for w in words if w not in qs.value_list('word', flat=True))
Django 1.7中也有一个默认值,但目前它没有区分update的默认值和create的默认值:
for w in words:
VectorSet.objects.update_or_create(word=w, session=session,
defaults={'weight': models.F('weight')+1})
因此,上面的代码将无法通过intmodels创建。F'weight'+1我们可以覆盖uuu int_uuuu方法,但太过粗糙而没有意义……IMO至少相关:在我看来非常好。
for w in words:
VectorSet.objects.update_or_create(word=w, session=session,
defaults={'weight': models.F('weight')+1})