Django4 中文入门教程 Django4.0 数据库访问优化-使用批量方法

2024-02-25 开发教程 Django4 中文入门教程 匿名 5

使用批量方法来减少SQL语句

批量创建

当创建对象时,尽可能使用 ​bulk_create()​ 方法来减少 SQL 查询数量。比如:

Entry.objects.bulk_create([
Entry(headline='This is a test'),
Entry(headline='This is only a test'),
])

要优于:

Entry.objects.create(headline='This is a test')
Entry.objects.create(headline='This is only a test')

批量更新

当更新对象时,尽可能使用 ​bulk_update()​ 方法来减少 SQL 查询数。给定对象的列表或查询集:

entries = Entry.objects.bulk_create([
Entry(headline='This is a test'),
Entry(headline='This is only a test'),
])

下面示例:

entries[0].headline = 'This is not a test'
entries[1].headline = 'This is no longer a test'
Entry.objects.bulk_update(entries, ['headline'])

要优于:

entries[0].headline = 'This is not a test'
entries[0].save()
entries[1].headline = 'This is no longer a test'
entries[1].save()

批量插入

当插入对象到 ​ManyToManyFields ​时,使用带有多个对象的 ​add()​ 来减少 SQL 查询的数量。举例:

my_band.members.add(me, my_friend)

要优于:

my_band.members.add(me)
my_band.members.add(my_friend)

其中 ​Bands ​和 ​Artists ​有多对多关系。
当不同的对象对插入到 ​ManyToManyField ​或者自定义的 ​through ​表被定义时,可以使用 ​bulk_create()​ 方法来减少 SQL 查询的数量。比如:

PizzaToppingRelationship = Pizza.toppings.through
PizzaToppingRelationship.objects.bulk_create([
PizzaToppingRelationship(pizza=my_pizza, topping=pepperoni),
PizzaToppingRelationship(pizza=your_pizza, topping=pepperoni),
PizzaToppingRelationship(pizza=your_pizza, topping=mushroom),
], ignore_conflicts=True)

要优于:

my_pizza.toppings.add(pepperoni)
your_pizza.toppings.add(pepperoni, mushroom)

批量删除

当从 ​ManyToManyFields ​删除对象时,可以使用带有多个对象的 ​remove()​ 来减少 SQL 查询的数量。比如:

my_band.members.remove(me, my_friend)

要优于:

my_band.members.remove(me)
my_band.members.remove(my_friend)

其中 ​Bands ​和 ​Artists ​有多对多关系。
当从 ​ManyToManyFields ​里删除不同的对象对时,可以在带有多种 ​through ​模型实例的 ​Q ​表达式上使用 ​delete()​ 来减少 SQL 查询的数量。比如:

from django.db.models import Q
PizzaToppingRelationship = Pizza.toppings.through
PizzaToppingRelationship.objects.filter(
Q(pizza=my_pizza, topping=pepperoni) |
Q(pizza=your_pizza, topping=pepperoni) |
Q(pizza=your_pizza, topping=mushroom)
).delete()

要优于:

my_pizza.toppings.remove(pepperoni)
your_pizza.toppings.remove(pepperoni, mushroom)