【问题标题】:Django .create() for each item in queryset? Like: Reporter.objects.all().article_set.create(...)查询集中每个项目的 Django .create()?喜欢:Reporter.objects.all().article_set.create(...)
【发布时间】:2020-12-06 23:15:21
【问题描述】:

https://docs.djangoproject.com/en/3.1/topics/db/examples/many_to_one/,

以 Django 的 Reporter/Article 作为我的实际问题的可比示例,我需要为我的查询集中的每个记者创建一篇新文章。

我现在的做法如下:

reporters = Reporter.objects.filter(...)
for reporter in reporters:
    article = Article()
    article.reporter = reporter
    ...
    article.save()

问题是我有 25k 的“记者”,所以处理请求需要很长时间并引发超时。

我想知道是否有更好的方法,有点像:

Reporter.objects.filter(...).article_set.create(...)

【问题讨论】:

  • 我最终保存了一个列表:reporter_values = Reporter.objects.filter(...).values_list('id') 然后使用列表理解,我在 python 中构建了每一篇文章:articles = [Article(reporter_id=value[0], ...) for value in reporter_values] 并完成了所有内容:Article.objects.bulk_create(articles) 这解决了问题第二,但是,如果有更好的方法来做到这一点,我很想知道。

标签: django django-models orm django-queryset crud


【解决方案1】:

我认为您的最佳解决方案是bulk_create()

类似这样的:

reporters = Reporter.objects.filter(...)

articles = []
for reporter in reporters:
    article = Article(reporter=reporter)
    ...
    articles.append(article)

Article.objects.bulk_create(articles)

它将允许您不进行 25k 数据库查询。

【讨论】:

  • 我基本上是这样做的,但我没有从 db 到 python 读取所有记者,而是只使用他们的 id 来创建文章:values_list('id')
  • reporter_values = Reporter.objects.filter(...).values_list('id') - 同一个数据库查询,所以这里没有优化。
  • 是的,这是一个更好的查询,因为有一点细节:它只带来来自记者的 'id'(我刚刚用reporter_values.query 进行了检查)。在我的真实场景中,我称之为“记者”实际上是一个更大的复杂对象,充满了长文本字段、数据等,所以它有很大的不同。但无论如何,毕竟我认为最大的改进来自bulk_create() 重构,它将db.connection.queries 减少到2 而不是9000,时间从120s 减少到1.2s。我将赞成您的问题,因为我认为它非常适合解决问题。
【解决方案2】:

您应该尝试执行以下操作:

reporters = Reporter.objects.filter(...)
for reporter in reporters:
    Article.objects.create(reporter=reporter, ....)

这应该更有效,但不确定它是否能解决您的问题。如果没有,您可能需要分批进行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-01
    • 2014-03-30
    • 1970-01-01
    • 2012-12-23
    • 2012-09-18
    • 1970-01-01
    • 1970-01-01
    • 2015-04-03
    相关资源
    最近更新 更多