- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
最近我遇到了以下问题:如何迭代真正的大数据查询以执行操作(比如为每个对象创建两个不同的对象)。如果您处理一个小查询集,这很简单:
for obj in Mymodel.objects.all():
create_corresponding_entries(obj)
现在尝试在包含 900k 个对象的查询集中执行此操作。可能您的电脑会死机,因为它会耗尽所有内存。那么我怎样才能懒惰地实现这一目标呢?无论您使用 Django ORM 还是 SQLAlchemy,都会出现同样的问题
最佳答案
尽管 Django ORM 提供了一个“惰性”查询集,但我一直在寻找的是一个生成器,它可以为我提供一种惰性获取对象的方法。 django 中的查询集并不是真正的惰性,它们是惰性的,直到您尝试访问它们,数据库将命中并获取 1M 条目。 SQLAlchemy 做同样的事情。如果您有 oracle 或 postgre 数据库,那么您很幸运,您可以使用受支持的服务器端游标。如果您使用 mysqldb 或 pymysql 方言,SQLAlchemy 还支持这些加上 mysql。我不确定服务器端游标在幕后是如何工作的。
更多信息
因此,如果您不符合上述任何一种情况,则必须想出一种方法来延迟获取这些对象。因为 Django ORM 和 SQLAlchemy 都支持通过将其转换为纯 SQL 查询来进行切片,所以我想我可以使用自定义生成器来对我需要的查询进行切片。
免责声明:该解决方案试图解决在本地转储大量数据的问题,它不会尝试最大限度地提高查询性能或与数据库相关的任何性能。
警告:与简单的 Mymodel.objects.all()
相比,这将导致对数据库的更多查询,但对您的 RAM 的挑战较小。
def lazy_bulk_fetch(max_obj, max_count, fetch_func, start=0):
counter = start
while counter < max_count:
yield fetch_func()[counter:counter + max_obj]
counter += max_obj
然后使用它例如:
fetcher = lazy_bulk_fetch(50, Mymodel.objects.count(), lambda: Mymodel.objects.order_by('id'))
for batch in fetcher:
make_actions(batch)
这将为我每次迭代获取 50 个对象的列表,直到达到我想要的最大数量。如果您在 Django 中将 make_actions(batch)
更改为 print(batch.query)
,您将看到如下内容:
SELECT "services_service"."id" FROM "services_service" LIMIT 50
SELECT "services_service"."id" FROM "services_service" LIMIT 50 OFFSET 50
SELECT "services_service"."id" FROM "services_service" LIMIT 50 OFFSET 100
SELECT "services_service"."id" FROM "services_service" LIMIT 50 OFFSET 150
同样的概念可以用于 slice
即 SQLAlchemy supports .在这种情况下的解决方案是相同的,但不是 python 切片,而是使用 SQLAlchemy 查询对象的 slice
函数
编辑: 据我所见,SQLAlchemy Query 类实现了 __getitem__
函数。 因此,对于 SQLAlchemy,您可以使用我为 Django 建议的完全相同的函数。如果您想显式使用 slice
函数,您将得到如下所示的结果: p>
def lazy_bulk_fetch(max_obj, max_count, fetch_func, start=0):
counter = start
while counter < max_count:
yield fetch_func().slice(counter, counter + max_obj)
counter += max_obj
无论如何你会这样调用它:
from sqlalchemy import func
fetcher = lazy_bulk_fetch(50, session.query(func.count(Mymodel.id)),
lambda: session.query(Mymodel).order_by(Mymodel.id))
这里有两个注意事项:
func.count
以便将其转换为服务器中的 COUNT
个 SQL 语句。如果您使用 len(session.query(Mymodel))
,您将在本地转储所有内容,找到它的长度,然后将其丢弃我使用 lambda
这样实现就像 django 一样。我也可以有
lazy_bulk_fetch(50, session.query(func.count(Mymodel.id)),
session.query(Mymodel).order_by(Mymodel.id))
但是我必须在我的函数中有
yield fetch_func.slice(counter, counter + max_obj)
编辑 #2: 我添加了排序,否则您无法确定在第 N 次运行中不会得到相同的结果。订购保证您将获得独特的结果。最好将 id 作为排序键,否则你不能确定你错过了一个结果(因为在第 N 次命中时,可能已经添加了一个新条目并且没有 id 的排序可能会导致你错过它或得到双重条目)
关于python - 如何从 django/sqlalchemy 处理的数据库中批量获取模型对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44206636/
我的一位教授给了我们一些考试练习题,其中一个问题类似于下面(伪代码): a.setColor(blue); b.setColor(red); a = b; b.setColor(purple); b
我似乎经常使用这个测试 if( object && object !== "null" && object !== "undefined" ){ doSomething(); } 在对象上,我
C# Object/object 是值类型还是引用类型? 我检查过它们可以保留引用,但是这个引用不能用于更改对象。 using System; class MyClass { public s
我在通过 AJAX 发送 json 时遇到问题。 var data = [{"name": "Will", "surname": "Smith", "age": "40"},{"name": "Wil
当我尝试访问我的 View 中的对象 {{result}} 时(我从 Express js 服务器发送该对象),它只显示 [object][object]有谁知道如何获取 JSON 格式的值吗? 这是
我有不同类型的数据(可能是字符串、整数......)。这是一个简单的例子: public static void main(String[] args) { before("one"); }
嗨,我是 json 和 javascript 的新手。 我在这个网站找到了使用json数据作为表格的方法。 我很好奇为什么当我尝试使用 json 数据作为表时,我得到 [Object,Object]
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
我听别人说 null == object 比 object == null check 例如: void m1(Object obj ) { if(null == obj) // Is thi
Match 对象 提供了对正则表达式匹配的只读属性的访问。 说明 Match 对象只能通过 RegExp 对象的 Execute 方法来创建,该方法实际上返回了 Match 对象的集合。所有的
Class 对象 使用 Class 语句创建的对象。提供了对类的各种事件的访问。 说明 不允许显式地将一个变量声明为 Class 类型。在 VBScript 的上下文中,“类对象”一词指的是用
Folder 对象 提供对文件夹所有属性的访问。 说明 以下代码举例说明如何获得 Folder 对象并查看它的属性: Function ShowDateCreated(f
File 对象 提供对文件的所有属性的访问。 说明 以下代码举例说明如何获得一个 File 对象并查看它的属性: Function ShowDateCreated(fil
Drive 对象 提供对磁盘驱动器或网络共享的属性的访问。 说明 以下代码举例说明如何使用 Drive 对象访问驱动器的属性: Function ShowFreeSpac
FileSystemObject 对象 提供对计算机文件系统的访问。 说明 以下代码举例说明如何使用 FileSystemObject 对象返回一个 TextStream 对象,此对象可以被读
我是 javascript OOP 的新手,我认为这是一个相对基本的问题,但我无法通过搜索网络找到任何帮助。我是否遗漏了什么,或者我只是以错误的方式解决了这个问题? 这是我的示例代码: functio
我可以很容易地创造出很多不同的对象。例如像这样: var myObject = { myFunction: function () { return ""; } };
function Person(fname, lname) { this.fname = fname, this.lname = lname, this.getName = function()
任何人都可以向我解释为什么下面的代码给出 (object, Object) 吗? (console.log(dope) 给出了它应该的内容,但在 JSON.stringify 和 JSON.parse
我正在尝试完成散点图 exercise来自免费代码营。然而,我现在只自己学习了 d3 几个小时,在遵循 lynda.com 的教程后,我一直在尝试确定如何在工具提示中显示特定数据。 This code
我是一名优秀的程序员,十分优秀!