【问题标题】:Using Django ORM for processing huge numbers of large records使用 Django ORM 处理大量大记录
【发布时间】:2012-10-29 23:58:08
【问题描述】:

我有一个包含大约 30k 记录的表,我正在尝试使用 Django 的 ORM 对其进行迭代和处理。每条记录存储几个二进制 blob,每个大小可以是几 MB,我需要对其进行处理并写入文件。

但是,由于内存限制,我在使用 Django 时遇到了麻烦。我的系统上有 8GB 内存,但在处理了大约 5k 条记录后,Python 进程消耗了全部 8GB 内存并被 Linux 内核杀死。我尝试了各种技巧来清除 Django 的查询缓存,例如:

  1. 定期调用MyModel.objects.update()
  2. 设置settings.DEBUG=False
  3. 通过gc.collect()定期调用Python的垃圾收集器

但是,这些似乎都没有任何明显的影响,并且我的进程继续经历某种内存泄漏,直到它崩溃。

还有什么我可以做的吗?

由于我一次只需要处理一条记录,并且在此过程中我不需要再次访问同一条记录,因此我不需要保存任何模型实例,或者一次加载多个实例。你如何确保只加载一条记录并且 Django 缓存 nothing 并在使用后立即取消分配所有内存?

【问题讨论】:

  • 为什么不在存储过程中进行处理?
  • 使用 settings.DEBUG=False,“Django 的查询缓存”应该不会有问题。我怀疑你的记忆问题在其他地方......
  • 你能发布你的代码吗,我已经在 django 中运行了作业,我在其中插入了超过一百万条记录,没有内存问题。如果我们查看您的代码,我们可能会看到占用所有内存的内容。
  • @MarwanAlsabbagh,奇怪的是,这个问题只在导出数据时出现,而不是在插入时出现。我也有可以毫无问题地插入数千条记录的工作。
  • @Cerin 是的,答案看起来完全解决了您的问题。很高兴知道以防我需要做类似的操作。

标签: python django django-orm


【解决方案1】:

尝试使用迭代器。

QuerySet 通常会在内部缓存其结果,以便重复 评估不会导致额外的查询。相比之下, iterator() 将直接读取结果,而不做任何缓存 QuerySet 级别(在内部,默认迭代器调用 iterator() 并缓存返回值)。对于返回大的 QuerySet 您只需要访问一次的对象数量,这可能会导致 更好的性能和显着减少的内存。

这是来自 django 文档的引用:https://docs.djangoproject.com/en/dev/ref/models/querysets/#iterator

【讨论】:

  • 哇,变化是巨大的。使用 iterator() 我的进程几乎没有注册任何内存使用情况。谢谢。
猜你喜欢
  • 1970-01-01
  • 2013-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多