Django:使用每个对象计算更新许多对象

时间:2016-02-29 01:17:03

标签: python django django-celery

这个问题是我问过yesterday的问题的延续:我还不确定post_save处理程序或第二个Celery任务是否是根据第一个结果更新多个对象的最佳方法芹菜任务,但我打算测试性能下线。以下是对正在发生的事情的回顾:

Celery task, every 30s:
Update page_count field of Book object based on conditions
                 |
post_save(Book)  |  
                 V
Update some field on all Reader objects w/ foreign key to updated Book 
(update will have different results per-Reader, thousands of Readers could be FKed to Book)

第一个任务可以保存~10个对象,需要更新每个对象的所有相关Reader对象。

无论哪个证明在post_save和另一个任务之间更好,他们必须完成同样的事情:在表中更新潜在的数十到数十万个对象,每个对象更新都是唯一的。可能我在post_save和Celery任务之间的选择取决于哪种方法实际上允许我实现这个目标。

由于我不能只使用一些queryset update()命令,我需要以某种方式调用一个方法或函数,根据第一个Celery任务的结果来计算字段的值,以及对象中的一些值。这是一个例子:

class Reader(models.Model):
    book = models.ForeignKey(Book)
    pages_read = models.IntegerField(default=0)
    book_finished = models.BooleanField(default=False)

    def determine_book_finished(self):
       if self.pages_read == book.page_count:
           self.book_finished = True
       else:
           self.book_finished = False

这是一个人为的例子,但如果第一个任务中的page_count已更新,我希望Readers所有Book个外国人重新计算book_finished determine_book_finished() - 并且循环查询集似乎是一种非常低效的方法。

我的想法是以某种方式立即在一个整个查询集上调用update()等模型方法,但是我找不到任何关于如何做这样的事情的文档 - 自定义查询集没有' t似乎是为了在查询集中超出内置Books功能的对象实际操作。

使用Celery的

This post是我发现的最有希望的东西,而且由于Django信号是同步的,因此使用另一个Celery任务也可以获得其他任何东西。因此,即使我仍然需要遍历查询集,它仍然是异步的,并且需要更新的任何查询集都可以由单独的任务处理,希望并行处理。

另一方面,this question似乎也有一个解决方案 - 使用post_save信号注册方法,这可能会在接收到信号后对所有对象运行该方法。这可能适用于需要更新的数千个对象,以及可能由同一任务更新的其他Readers及其数千个关联book_finished然后还需要更新吗?

做我在这里尝试做的事情是否有最好的做法?

编辑:我意识到我可以采用另一种方式 - 使@property def book_finished: if self.pages_read == self.book.page_count: if self.book.page_count == self.book.planned_pages: return True else: return False 字段成为在运行时确定的属性,而不是静态字段。

if

这与我的实际代码非常接近,第一个elif分支包含几个if-else分支,每个分支都有自己的if,总最大深度为3 lm.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER) 秒。

在我可以调整大量测试数据并模拟许多同时用户之前,我可能坚持使用此选项,因为它肯定有效(目前)。我不太喜欢在每次检索时计算属性,但是从一些快速的研究来看,它似乎不是一种过于缓慢的方法。

0 个答案:

没有答案