Python 如何使 Django QuerySet 批量删除()更高效
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4867852/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to make Django QuerySet bulk delete() more efficient
提问by svintus
Setup:
Django 1.1.2, MySQL 5.1
设置:
Django 1.1.2,MySQL 5.1
Problem:
问题:
Blob.objects.filter(foo = foo) \
.filter(status = Blob.PLEASE_DELETE) \
.delete()
This snippet results in the ORM first generating a SELECT * from xxx_blob where ...query, then doing a DELETE from xxx_blob where id in (BLAH);where BLAH is a ridiculously long list of id's. Since I'm deleting a large amount of blobs, this makes both me and the DB very unhappy.
这个片段导致 ORM 首先生成一个SELECT * from xxx_blob where ...查询,然后做一个DELETE from xxx_blob where id in (BLAH);where BLAH 是一个长得可笑的 id 列表。由于我删除了大量的 blob,这让我和 DB 都非常不高兴。
Is there a reason for this? I don't see why the ORM can't convert the above snippet into a single DELETE query. Is there a way to optimize this without resorting to raw SQL?
是否有一个原因?我不明白为什么 ORM 不能将上面的代码片段转换为单个 DELETE 查询。有没有办法在不求助于原始 SQL 的情况下优化它?
采纳答案by Dominic Santos
Not without writing your own custom SQL or managers or something; they are apparently working on it though.
不是没有编写您自己的自定义 SQL 或管理器或其他东西;不过,他们显然正在努力。
回答by David
Bulk deleteis already part of django
批量删除已经是 Django 的一部分
Keep in mind that this will, whenever possible, be executed purely in SQL
请记住,只要有可能,这将完全在 SQL 中执行
回答by Anoyz
For those who are still looking for an efficient way to bulk delete in django, here's a possible solution:
对于那些仍在寻找在 Django 中批量删除的有效方法的人,这里有一个可能的解决方案:
The reason delete()may be so slow is twofold: 1) Django has to ensure cascade deleting functions properly, thus looking for foreign key references to your models; 2) Django has to handle pre and post-save signals for your models.
delete()可能这么慢的原因有两个:1) Django 必须确保正确的级联删除功能,从而查找模型的外键引用;2) Django 必须为您的模型处理保存前和保存后的信号。
If you know your models don't have cascade deleting or signals to be handled, you can accelerate this process by resorting to the private API _raw_deleteas follows:
如果您知道您的模型没有级联删除或要处理的信号,您可以通过使用私有 API 来加速此过程,_raw_delete如下所示:
queryset._raw_delete(queryset.db)
More details in here. Please note that Django already tries to make a good handling of these events, though using the raw delete is, in many situations, much more efficient.
更多细节在这里。请注意,Django 已经尝试很好地处理这些事件,尽管在许多情况下使用原始删除更有效。

