如何从数据存储中获取超过1000条记录,并将所有记录放入单个列表中以传递给Django?
如何从数据存储中获取超过1000条记录,并将所有记录放入单个列表中以传递给Django?
仅记录一下 - 现在已经取消了最多1000个条目的获取限制:
http://googleappengine.blogspot.com/2010/02/app-engine-sdk-131-including-major.html
引用:
不再有1000个结果限制 - 是的:随着游标的添加以及过去几个月中许多更小的数据存储稳定性和性能改进的总结,我们现在足够有信心完全删除最大结果限制。无论您是进行获取、迭代还是使用游标,都没有结果数量的限制。
App Engine提供了一种很好的“分页”方式,通过按键排序并使用最后一个键作为下一个偏移量,每次可以获取1000个结果。他们甚至在此处提供了一些示例代码:
http://code.google.com/appengine/docs/python/datastore/queriesandindexes.html#Queries_on_Keys
虽然他们的示例将查询分散到许多请求中,但您可以将页面大小从20更改为1000,并在循环中查询,结合查询集。此外,您可能会使用itertools连接查询,而不是在需要之前对它们进行评估。
例如,要计算1000以后有多少行:
class MyModel(db.Expando):
@classmethod
def count_all(cls):
"""
Count *all* of the rows (without maxing out at 1000)
"""
count = 0
query = cls.all().order('__key__')
while count % 1000 == 0:
current_count = query.count()
if current_count == 0:
break
count += current_count
if current_count == 1000:
last_key = query.fetch(1, 999)[0].key()
query = query.filter('__key__ > ', last_key)
return count
如果您实际上将超过1000个结果返回给用户,那么我认为存在比数据存储不允许这样做更大的问题。
需要返回这么多的结果可能有一个(合法的)原因,即如果您正在对数据进行大量操作并呈现摘要(例如所有这些数据的平均值是多少)。这个问题的解决办法(在Google I/O talk中有讨论)是随着数据的到来实时计算摘要数据并保存它们。
你不能。
FAQ的一部分说明,无法访问查询结果中超过1000行的数据,增加“OFFSET”只会导致结果集更短,
例如:OFFSET 999 --> 只返回1个结果。
来自维基百科:
App Engine将从每个Datastore调用返回的实体获取限制为最多1000行。大多数Web数据库应用程序使用分页和缓存,因此不需要一次获取这么多数据,因此在大多数情况下,这不是问题。[需要引证]如果应用程序需要每个操作超过1,000条记录,则可以使用其自己的客户端软件或Ajax页面对无限数量的行执行操作。
来自 http://code.google.com/appengine/docs/whatisgoogleappengine.html
另一个服务限制的例子是查询返回的结果数。查询最多可以返回1,000个结果。将返回更多结果的查询仅返回最大结果。在这种情况下,执行此类查询的请求不太可能在超时之前返回请求,但是该限制是为了节省数据存储上的资源。
来自 http://code.google.com/appengine/docs/datastore/gqlreference.html
注意:LIMIT子句最多为1000。如果指定的限制大于最大值,则使用最大值。这个最大值也适用于GqlQuery类的fetch()方法。LIMIT 1000 OFFSET 0
将返回1000行,
和
LIMIT 1000 OFFSET 1000
将返回0行,因此无法使用单个查询语法手动或使用API获取2000个结果。
是在表上创建数值索引,即:
SELECT * FROM Foo WHERE ID > 0 AND ID < 1000
SELECT * FROM Foo WHERE ID >= 1000 AND ID < 2000
如果您的数据或查询不能有这个“ID”硬编码标识符,那么您就没有好运气了。
这个1K限制问题已经解决。
query = MyModel.all()
for doc in query:
print doc.title
通过将 Query 对象视为可迭代的对象:迭代器以小批量从数据存储库中检索结果,使应用程序可以停止对结果进行迭代,以避免获取不必要的内容。当检索到与查询匹配的所有结果时,迭代停止。与 fetch() 一样,迭代器接口不会缓存结果,因此从 Query 对象创建新的迭代器将重新执行查询。
最大批处理大小为1K,同时仍具有自动 Datastore 配额。
但是,在计划1.3.1 SDK中,他们引入了可以序列化和保存的游标,以便未来调用可以从它上次停止的位置开始查询。
当记录超过1000条时,通过远程API获取数据仍然存在问题。我们编写了这个小函数来分块迭代表中的数据:
def _iterate_table(table, chunk_size = 200):
offset = 0
while True:
results = table.all().order('__key__').fetch(chunk_size+1, offset = offset)
if not results:
break
for result in results[:chunk_size]:
yield result
if len(results) < chunk_size+1:
break
offset += chunk_size
。@classmethod
def get_all(cls):
q = cls.all()
holder = q.fetch(1000)
result = holder
while len(holder) == 1000:
holder = q.with_cursor(q.cursor()).fetch(1000)
result += holder
return result
这种方法可以规避每个模型的1000次查询限制,而无需考虑其他事情。我想实现一个键版本也同样容易。
entities = []
for entity in Entity.all():
entities.append(entity)
entities = Entity.all().fetch(999999)
Entity.all().fetch(Entity.all().count())
返回最大值1000,不建议使用。