【发布时间】:2019-09-06 14:38:56
【问题描述】:
我将 Django 1.11 与 MySQL 一起使用。在短期内升级到 2 是不可行的,因此不是我当前问题的可接受解决方案,但提到 Django 2 的答案可能会帮助其他人,所以请随时发布它们。
我需要对表中的所有行执行数据迁移。行数少于 40000,但它们非常大 - 其中两列是大约 15KB 的 JSON,在加载模型时会被解析。 (这些是我在数据迁移中需要使用的行,所以我不能defer他们)
为了不将所有对象同时加载到内存中,我想我会使用queryset.iterator,它一次只解析第 100 行。如果我所做的只是读取结果,这很好用,但是如果我执行另一个查询(例如到save 其中一个对象),那么一旦我到达当前 100 个结果块的末尾,下一个 100 个结果块是未获取,迭代器结束。
好像fetchmany 从中获取行的结果集已经丢失。
使用./manage.py shell来说明场景
(假设存在 40000 个具有顺序 id 的 MyModel)
iterator = app.models.MyModel.objects.iterator()
for obj in iterator:
print(obj.id)
上面按预期打印了 1 到 40000 的 id。
iterator = app.models.MyModel.objects.iterator()
for obj in iterator:
print(obj.id)
obj.save()
上面只打印 ids 1 到 100
iterator = app.models.MyModel.objects.iterator()
for obj in iterator:
print(obj.id)
if obj.id == 101:
obj.save()
上面只打印 ids 1 到 200
将obj.save 替换为对数据库进行查询的任何其他内容(例如app.models.OtherModel.objects.first())具有相同的结果。
在使用 queryset 迭代器时是否根本不可能进行另一个查询?有没有其他方法可以达到同样的目的?
谢谢
【问题讨论】:
-
使用paginator 并循环浏览所有页面怎么样?
-
使用 Paginator 是一个潜在的解决方案,谢谢。我调查并在我的答案中添加了细节。但是我仍然想了解迭代器发生了什么。
标签: django django-1.11 django-mysql