Python 如何在django中使用查找和条件相关插入执行插入?
我试图通过django优化大型数据集的数据库插入。 这里有一个简单的示例模型,足以说明我面临的问题Python 如何在django中使用查找和条件相关插入执行插入?,python,sql,django,database,sqlite,Python,Sql,Django,Database,Sqlite,我试图通过django优化大型数据集的数据库插入。 这里有一个简单的示例模型,足以说明我面临的问题 class School(models.Model): name = models.CharField(max_length=32) postcode = models.CharField(max_length=8) class Student(models.Model): name = models.CharField(max_length=32) school
class School(models.Model):
name = models.CharField(max_length=32)
postcode = models.CharField(max_length=8)
class Student(models.Model):
name = models.CharField(max_length=32)
school = models.ForeignKey(School)
last_updated = models.DateTimeField(blank=True, null=True)
first_registered = models.DateTimeField(blank=True, null=True)
给出了上面的示例模型。我目前可以用以下方式创建行
school = app.models.School.objects.get_or_create(name='School 1', postcode='AB12 3CD')
student = app.models.Student.objects.create(name='Student 1', school=school[0])
这在简单的“入门”案例中效果很好,但在扩展到更大的数据集和具有更多关系的更复杂模型时存在潜在问题
- 学校条目每次都需要数据库往返
- 比赛条件是可能的
- 有一个学校和学生数据的主列表
- 学生和学校名单每天更新
- 数据没有特定的顺序
- 以前的数据可能存在,但也可以删除
- 以前的数据也可能会更新(超出此问题的范围)
- 如果删除,则表示该学生不再是学生
# See if the student already exists and is assigned to the school in the data set.
# If it does exist, get the database to update the last updated date and the first registration dates if needs be.
#
# Note: These updates are necessary as it is possible that data is imported in non-chronological order.
updated_fields = app.models.Student.objects.filter(
name=data['student_name'],
school__name=data['school_name'],
school__postcode=data['school_postcode'],
).update(
last_updated=Case(
When(last_updated__lt=data['last_updated'], then=data['last_updated']),
default=F('last_updated')
),
first_registered=Case(
When(first_registered_gt=data['first_registered'], then=data['first_registered']),
default=F('first_registered')
)
)
我面临的问题是,当我插入新数据时,我会被困在多个数据库查询中。学校数量远少于学生,而且增加速度较慢。
除了最初的导入,在所有后续的每日更新中,99.9%的时间学校数据已经存在于数据库中,学生只需要分配
目前,我的导入实际上是以如下的原始方式工作的,并且有更多的FK查找,因此我热衷于减少数据库往返
for entry in data:
school = app.models.School.objects.get_or_create(name=entry['school_name'], postcode=entry['school_postcode'])
student = app.models.Student.objects.create(name=data['student_name'], school=school[0])
我想做的是将get_或_create移到create语句中,如果插入点不存在,则让它在数据库中创建它。我认为正确的方法是让数据库完成所有的工作
这样做的目的是在每次插入时传递所有学生和学校信息。然后,插入查询应尝试查找学校信息,并将该条目分配给学生的FK。
如果未返回结果,则应创建学校,然后为其分配结果FK
对于SQL,我发现了一个类似的问题。
我想这就是我想要的,但有一个关键区别,我的查询应该在查找失败的情况下创建条目
我想知道是否有人知道如何在django中做到这一点,也许可以使用WHERE、CASE等功能。。?
如果无法通过ORM实现,则欢迎通过原始SQL提供帮助
仅供参考,我目前正在运行django 1.10,升级不是问题。我正在使用sqlite后端(只是为了方便,而不是偏好或特性)
非常感谢,
安迪