Skip to main content

用于 Django 模型管理器的 bulk_update_or_create

项目描述

django-bulk-update-or-create

测试 测试覆盖率状态 PyPi 上的当前版本 每月下载量 PyPI - Python 版本 PyPI - Django 版本

每个使用 Django ORM 的人最终都会发现自己在做批处理update_or_create操作:从外部源摄取文件,与外部 API 同步等。

如果记录的数量很大,那么缓慢的情况QuerySet.update_or_create会很突出:使用起来非常实用,但它总是一个SELECT接一个INSERT(如果 select 没有返回任何内容)或UPDATE/ .save(如果返回)。

在线搜索表明,这确实发生在不少人身上,尽管它似乎不是任何好的解决方案:

  • bulk_create如果您知道所有记录都是新的(并且您没有使用多表继承),那么速度真的很快
  • bulk_update做了一些很好的巫术来用相同的UPDATE语句更新几条记录(使用一个巨大的WHERE条件CASE),但你需要确保它们都存在
  • UPSERTs (INSERT .. ON DUPLICATE KEY UPDATE)看起来很有趣(不同包上的 TODO)但它们会受到bulk_create限制 ==> 不能在具有多表继承的模型上使用

这个包试图解决这个引入bulk_update_or_create模型 QuerySet/Manager 的问题:

  • update_or_create(1 SELECT + 1 INSERT/UPDATE) * N
  • bulk_update_or_create1 BIG_SELECT + 1 BIG_UPDATE + (lte_N) INSERT

对于一批记录:

  • SELECT全部来自数据库(基于match_field参数)
  • 更新内存中的记录
  • 用于bulk_update那些
  • 在剩余的每个上使用INSERT/.create

( SOFTCORE )性能测试看起来很有希望,时间减少了 70% 以上(平均):

$ make testcmd
# default - sqlite
DJANGO_SETTINGS_MODULE=settings tests/manage.py bulk_it
loop of update_or_create - all creates: 3.966486692428589
loop of update_or_create - all updates: 4.020653247833252
loop of update_or_create - half half: 3.9968857765197754
bulk_update_or_create - all creates: 2.949239730834961
bulk_update_or_create - all updates: 0.15633511543273926
bulk_update_or_create - half half: 1.4585723876953125
# mysql
DJANGO_SETTINGS_MODULE=settings_mysql tests/manage.py bulk_it
loop of update_or_create - all creates: 5.511938571929932
loop of update_or_create - all updates: 5.321666955947876
loop of update_or_create - half half: 5.391834735870361
bulk_update_or_create - all creates: 1.5671980381011963
bulk_update_or_create - all updates: 0.14612770080566406
bulk_update_or_create - half half: 0.7262606620788574
# postgres
DJANGO_SETTINGS_MODULE=settings_postgresql tests/manage.py bulk_it
loop of update_or_create - all creates: 4.3584535121917725
loop of update_or_create - all updates: 3.6183276176452637
loop of update_or_create - half half: 4.145816087722778
bulk_update_or_create - all creates: 1.044851541519165
bulk_update_or_create - all updates: 0.14954638481140137
bulk_update_or_create - half half: 0.8407495021820068

安装

pip install django-bulk-update-or-create

将其添加到您的INSTALLED_APPS列表中settings.py

用法

  • 用作BulkUpdateOrCreateQuerySet模型的经理
from django.db import models
from bulk_update_or_create import BulkUpdateOrCreateQuerySet


class RandomData(models.Model):
    objects = BulkUpdateOrCreateQuerySet.as_manager()

    uuid = models.IntegerField(unique=True)
    data = models.CharField(max_length=200, null=True, blank=True)
  • 称呼bulk_update_or_create
items = [
    RandomData(uuid=1, data='data for 1'),
    RandomData(uuid=2, data='data for 2'),
]
RandomData.objects.bulk_update_or_create(items, ['data'], match_field='uuid')
  • 或使用上下文管理器,如果您要更新大量项目,因为它管理批处理队列
with RandomData.objects.bulk_update_or_create_context(['data'], match_field='uuid', batch_size=10) as bulkit:
    for i in range(10000):
        bulkit.queue(RandomData(uuid=i, data=i + 20))

bulk_update_or_create支持yield_objects=True,因此您可以迭代创建/更新的对象。
bulk_update_or_create_context向指定为的回调函数提供相同的信息status_cb

文档

在制品

去做

  • 文档!
  • 添加bulk_create用于创建的选项:断言模型不是多表(如果启用)
  • case_insensitive_match修复排序规则混乱:应该删除关键字 arg并在运行时检测排序规则
  • 添加对多个的支持match_field- 可能需要使用WHERE (K1=X and K2=Y) or (K1=.. and K2 =..)而不是IN那些,因为该 SQL 标准似乎还没有被广泛采用
  • 完成后链接到UPSERT替代包!

下载文件

下载适用于您平台的文件。如果您不确定要选择哪个,请了解有关安装包的更多信息。

源分布

django-bulk-update-or-create-0.3.0.tar.gz (8.0 kB 查看哈希)

已上传 source

内置分布

django_bulk_update_or_create-0.3.0-py3-none-any.whl (7.5 kB 查看哈希

已上传 py3