from django.db import transaction
@transaction.atomic
def viewfunc(request):
# This code executes inside a transaction.
do_stuff()
以及作为上下文管理器:
from django.db import transaction
def viewfunc(request):
# This code executes in autocommit mode (Django's default).
do_stuff()
with transaction.atomic():
# This code executes inside a transaction.
do_more_stuff()
4条答案
按热度按时间col17t5w1#
EDITED:
commit_on_success
已过时,在Django 1.8中已被移除。请使用transaction.atomic
。请参阅Fraser Harris的answer。实际上这比你想象的要容易。你可以在Django中使用transactions。这些批量数据库操作(特别是保存、插入和删除)合并成一个操作。我发现最容易使用的是
commit_on_success
。本质上你可以把数据库保存操作 Package 成一个函数,然后使用commit_on_success
装饰器。这将大大提高速度。如果任何一项失败,您还将获得回滚的好处。如果您有数百万个保存操作,那么您可能必须使用
commit_manually
和transaction.commit()
以块的形式提交它们,但我很少需要这样做。2nc8po8w2#
Django 1.6的新特性是原子的,一个简单的API来控制数据库事务。
atomic既可以用作装饰器:
以及作为上下文管理器:
遗留的
django.db.transaction
函数autocommit()
,commit_on_success()
,和commit_manually()
已被弃用,并将在Django 1.8中移除。c86crjj03#
我想这就是你要找的方法:https://docs.djangoproject.com/en/dev/ref/models/querysets/#bulk-create
从文档复制的代码:
实际上,它看起来像:
根据文档,这将执行单个查询,而不管列表的大小(SQLite3上最多999个条目),这对于
atomic
装饰器来说是不可能的。这里有一个重要的区别。从OP的问题中听起来,他试图 * 批量创建 * 而不是 * 批量保存 *。
atomic
装饰器是 * 保存 * 的最快解决方案,但不是 * 创建 *。zazmityj4#
"如何将大量save()调用聚合到单个数据库操作中?"
你不需要这样做。Django已经为你管理了一个缓存。你不能通过尝试保存来改善它的DB缓存。
"写入性能问题可能与创建大量行有关"
正确。
SQLite是相当慢的。这就是它的方式。查询比大多数其他数据库的快。写是相当慢。
考虑更严重的架构更改,您是否在Web事务期间加载行(例如,批量上载文件并从这些文件加载DB)?
如果你在一个web事务中进行批量加载,停止。你需要做一些更聪明的事情。使用celery或其他"批处理"工具在后台进行加载。
我们尝试将自己限制在Web事务中的文件验证,并在用户不等待HTML页面时执行加载。