使用计算在 Django 中批量更新
Bulk update in django with calculations
我的项目中有 2 个模型:
class Currency(models.Model):
title = models.CharField(max_length=100, unique=True)
value = models.FloatField()
class Good(models.Model):
name = models.CharField(max_length=100)
slug = SlugField(max_length=100, unique=True)
cost_to_display = models.IntegerField(default=0)
cost_in_currency = models.IntegerField()
currency = models.ForeignKey(Currency)
这种模式的想法是加快按价格搜索,并以一种货币显示所有商品。
因此,我需要一些挂钩来更新所有商品,以防汇率更新。
原始 sql 看起来像这样
mysql> update core_good set cost_to_display = cost_in_currency * (select core_currency.value from core_currency where core_currency.id = currency_id ) ;
Query OK, 663 rows affected (0.10 sec)
Rows matched: 7847 Changed: 663 Warnings: 0
运行速度非常快。尽管我尝试像这样在 django admin 中实现相同的功能(使用 bulk-update):
def save_model(self, request, obj, form, change):
"""Update rate values"""
goods = Good.objects.all()
for good in goods:
good.cost_to_display = good.cost_in_currency * good.currency.value
bulk_update(goods)
obj.save()
用这种方式通过 django admin 更新所有记录最多需要 20 分钟。
我做错了什么?更新所有价格的正确方法是什么?
这纯粹是未经测试的,但在我看来是可行的:
from django.db.models import F
Good.objects.all().update(cost_to_display=F('cost_in_currenty') * F('currency__value'))
即使你在调用bulk_update
,你仍然循环遍历所有商品,这就是你的过程缓慢的原因。
编辑:
这行不通,因为 F()
不支持连接字段。可以使用原始查询来完成。
对于未来的读者:代码中对 good.currency
的任何调用都会访问数据库。考虑使用 select_related
在一个查询中获取 Currency
和 Good
对象:
goods = Good.objects.select_related('currency')
现在 Django 自版本 2.2 docs
以来带有 bulk_update
方法
我的项目中有 2 个模型:
class Currency(models.Model):
title = models.CharField(max_length=100, unique=True)
value = models.FloatField()
class Good(models.Model):
name = models.CharField(max_length=100)
slug = SlugField(max_length=100, unique=True)
cost_to_display = models.IntegerField(default=0)
cost_in_currency = models.IntegerField()
currency = models.ForeignKey(Currency)
这种模式的想法是加快按价格搜索,并以一种货币显示所有商品。 因此,我需要一些挂钩来更新所有商品,以防汇率更新。
原始 sql 看起来像这样
mysql> update core_good set cost_to_display = cost_in_currency * (select core_currency.value from core_currency where core_currency.id = currency_id ) ;
Query OK, 663 rows affected (0.10 sec)
Rows matched: 7847 Changed: 663 Warnings: 0
运行速度非常快。尽管我尝试像这样在 django admin 中实现相同的功能(使用 bulk-update):
def save_model(self, request, obj, form, change):
"""Update rate values"""
goods = Good.objects.all()
for good in goods:
good.cost_to_display = good.cost_in_currency * good.currency.value
bulk_update(goods)
obj.save()
用这种方式通过 django admin 更新所有记录最多需要 20 分钟。
我做错了什么?更新所有价格的正确方法是什么?
这纯粹是未经测试的,但在我看来是可行的:
from django.db.models import F
Good.objects.all().update(cost_to_display=F('cost_in_currenty') * F('currency__value'))
即使你在调用bulk_update
,你仍然循环遍历所有商品,这就是你的过程缓慢的原因。
编辑:
这行不通,因为 F()
不支持连接字段。可以使用原始查询来完成。
对于未来的读者:代码中对 good.currency
的任何调用都会访问数据库。考虑使用 select_related
在一个查询中获取 Currency
和 Good
对象:
goods = Good.objects.select_related('currency')
现在 Django 自版本 2.2 docs
以来带有bulk_update
方法