【发布时间】:2020-11-08 19:11:08
【问题描述】:
感谢您阅读我的问题!我将 django (3.0.8) 与 postgres 12 一起使用。下面是 Inventory 的简化模型。大约有 100 万条记录。
class Inventory(models.Model):
account = models.ForeignKey(Account, on_delete=models.PROTECT)
item_id = models.LargeIntegerField(unique=True, db_index=True)
amount = models.IntegerField()
每小时我们都会通过 REST API 收到一个帐户的新 snapshots,例如acc_0。它包含完整的项目列表(约 10 万条记录),而不是增量。我想应用 3 个操作:
- 如果
item_id不在新的snapshots中,则设置amount=0 where account==acc_0。 - 如果
item_id在新的snapshots中设置amount=snapshot['amount'] where account==acc_0。 - 如果
snapshot['item_id']不在Inventory.item_id中,则创建新项目
每次,大多数项目已经存在于 DB 中并且它们的数量没有变化,即真正的 delta 非常小(100-1k 记录)。
我现在做的似乎效率不高:
with transaction.atomic():
new_items = {}
update_items = {}
Inventory.objects.filters(account=acc_0).update(amount=0)
for snapshot in snapshots:
item_id = snapshot['item_id']
results = Inventory.objects.filter(item_id=item_id)
if len(results) == 0:
new_items[item_id] = Inventory(...)
else:
item = result[0]
item.amount = snapshot['amount']
update_items[item_id] = item
Inventory.objects.bulk_create(new_items.values())
Inventory.objects.bulk_update(update_items.values(), ['amount'])
我想知道我是否应该将快照上传到临时表并使用 UPDATE SET CASE JOIN、INSERT INTO SELECT NOT EXISTS 或者更好的是有一个更 Pythonic 的方式。
有一个类似的问题:Django Mass Update/Insert Performance 但它也是开放的。
【问题讨论】:
标签: python sql django postgresql join