Django批处理/批量更新还是创建?

2024-04-19 00:52:57 发布

您现在位置:Python中文网/ 问答频道 /正文

我在数据库里有数据,需要在船期更新。数据源返回在该时间点可用的所有数据,因此将包括数据库中尚未包含的新数据。

当我循环遍历源数据时,如果可能的话,我不想单独写1000次。

有没有像update_or_create这样的东西可以分批工作?

有一种想法是将update_or_create与手动事务结合使用,但我不确定这是将单个写操作排队,还是将所有写操作合并到一个SQL插入中?

或者类似地,在循环中对具有update_or_create的函数使用@commit_on_success()可以工作吗?

除了翻译数据并将其保存到模型中之外,我对这些数据什么也不做。任何东西都不依赖于循环期间存在的模型


Tags: or数据函数模型数据库sqlcreate时间
1条回答
网友
1楼 · 发布于 2024-04-19 00:52:57

批量更新将是一个upsert命令,就像@imposeren所说的,Postgres 9.5提供了这种能力。我认为Mysql 5.7也可以(参见http://dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html),这取决于您的确切需求。也就是说,使用db游标可能是最简单的。没什么问题,因为虫子还不够。

沿着这条线的东西应该有用。这是一个伪代码,所以不要只是剪切粘贴,但概念是为你。

class GroupByChunk(object):
    def __init__(self, size):
        self.count = 0
        self.size = size
        self.toggle = False

    def __call__(self, *args, **kwargs):
        if self.count >= self.size:  # Allows for size 0
            self.toggle = not self.toggle
            self.count = 0
        self.count += 1
        return self.toggle

def batch_update(db_results, upsert_sql):
    with transaction.atomic():
        cursor = connection.cursor()   
        for chunk in itertools.groupby(db_results, GroupByChunk(size=1000)):
            cursor.execute_many(upsert_sql, chunk)

假设如下:

  • db_results是某种结果迭代器,在列表或字典中
  • 来自db_results的结果可以直接馈送到原始sql exec语句中
  • 如果任何批处理更新失败,您将回滚所有更新。如果要将每个块移动到,只需将with块向下推一点

相关问题 更多 >