在 Django 中聚合 save()s?

新手上路,请多包涵

我正在使用带有 sqlite 后端的 Django,并且写入性能是一个问题。我可能会在某个阶段毕业到一个“合适的”数据库,但目前我被 sqlite 困住了。我认为我的写入性能问题可能与我正在创建大量行的事实有关,并且大概每次我 save() 一次它都会锁定、解锁和同步磁盘上的数据库。

如何将大量 save() 调用聚合到单个数据库操作中?

原文由 kdt 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 621
2 个回答

已编辑: commit_on_success 已弃用并在 Django 1.8 中被删除。请改用 transaction.atomic 。请参阅弗雷泽哈里斯的 回答

实际上,这比你想象的要容易。您可以在 Django 中使用 事务。这些批处理数据库操作(特别是保存、插入和删除)成为一个操作。我发现最容易使用的是 commit_on_success 。本质上,您将数据库保存操作包装到一个函数中,然后使用 commit_on_success 装饰器。

 from django.db.transaction import commit_on_success

@commit_on_success
def lot_of_saves(queryset):
    for item in queryset:
        modify_item(item)
        item.save()

这将有巨大的速度提升。如果任何项目失败,您还将获得回滚的好处。如果您有数百万个保存操作,那么您可能必须使用 commit_manuallytransaction.commit() 将它们提交到块中,但我很少需要它。

希望有帮助,

将要

原文由 JudoWill 发布,翻译遵循 CC BY-SA 4.0 许可协议

“如何将大量 save() 调用聚合到单个数据库操作中?”

你不需要。 Django 已经为你管理了一个缓存。您无法通过尝试保存来改进它的数据库缓存。

“写入性能问题可能与我正在创建大量行的事实有关”

正确的。

SQLite 很慢。它就是这样儿的。查询比大多数其他数据库更快。写入速度很慢。

考虑更严重的架构变化。您是否在网络事务期间加载行(即批量上传文件并从这些文件加载数据库)?

如果您在 Web 事务中进行批量加载,请停止。你需要做一些更聪明的事情。使用 celery 或使用其他一些“批处理”工具在后台进行加载。

我们尝试将自己限制在 Web 事务中的文件验证,并在用户不等待他们的 HTML 页面时进行加载。

原文由 S.Lott 发布,翻译遵循 CC BY-SA 2.5 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题