如何获取超过1000?
-
06-07-2019 - |
题
我怎么可以获取超过1000记录数据存储和把所有在一个单一的名单传递给django?
解决方案
其他提示
仅为记录 - 现在取消了1000个条目的限制:
http://googleappengine.blogspot。 COM / 2010/02 / APP-发动机-SDK-131-包括-major.html
报价:
不再有1000个结果限制 - 那就是 右:加上游标和 许多小人物的高潮 数据存储的稳定性和性能 过去几个月的改进, 我们现在有足够的信心去除 最大限度的结果限制。 无论你是在取, 迭代,或使用Cursor,有 对结果数量没有限制。
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
每次出现此限制时,我总是想知道“为什么你需要超过1,000个结果?”您是否知道Google自己没有提供超过1,000个结果?试试这个搜索: http://www.google.ca/search?hl=en&client=firefox-a&rls=org.mozilla:en-US:official&hs=qhu&q=1000+results&start = 1000& sa = N 直到最近我还不知道,因为我从来没有花时间点击查询的第100页搜索结果。
如果您实际上将超过1,000个结果返回给用户,那么我认为手头上存在的问题比数据存储不允许您这样做的事情要大。
如果您对数据执行大型操作并显示摘要(例如,所有这些数据的平均值),那么需要许多结果的一个可能(合法)理由是。这个问题的解决方案(在Google I / O谈话中讨论过)是在动态计算摘要数据,并将其保存。
你不能。
部分常见问题的国家,有没有办法你可以访问之外行1000的查询,增加了"抵消"只会导致在更短的结果,
即:偏999-->1的结果回来。
从维基百科:
应用程序的发动机限制了最大行 回从一种实体得到1000 行每数据储存的呼吁。大多数网络 数据库应用程序的使用,并呼 缓存,因此不需要这个 多数据,因此这是一个 非的问题在大多数情况。[引文 需要]如果一个应用程序需要更多 于1000记录每操作, 可以使用其自己的客户端的软件 或Ajax页执行 上操作无数 排。
从 http://code.google.com/appengine/docs/whatisgoogleappengine.html
另一个例子服务的限制是 数返回的结果 查询。查询可以返回的至多 1,000的结果。查询会 返回的结果只有回报的 最大。在这种情况下,一个请求 执行这种查询不可能 回请求之前的超时, 但是,该限制是在地方保护 资源数据存储库。
从 http://code.google.com/appengine/docs/datastore/gqlreference.html
注:一个限制条款具有最大的 1000.如果一个限制大于最大的是指定的,最大的是 使用。这同样的最大适用于 获取()方法GqlQuery类。
注:像的偏参数 的获取()方法,一种抵消在一GQL 查询串不会降低 若干实体获取的 数据存储库。它只会影响 结果是返回的获取() 法。查询一个偏移了 性能特征, 线性地对应的抵消 大小。
从 http://code.google.com/appengine/docs/datastore/queryclass.html
限制和偏参数的控制 许多结果都取自的 数据存储库,以及有多少返回 通过获取()方法:
该数据存储库获取偏+结果限制应用程序。第一个抵消的结果 不 跳过的数据储存本身。
的获取()方法跳过第一偏移的结果,然后返回的其余部分(限制的结果)。
查询有的性能特征相符 线性偏移量加的限制。
这意味着什么
如果你有一个单一的查询,是没有办法要求任何东西范围之外的0-1000年。
增加的抵消将仅提高0,所以
LIMIT 1000 OFFSET 0
将返回1000行,
和
LIMIT 1000 OFFSET 1000
将返回 0行, ,因此,使它不可能的,用一个单一的查询语法,取2000年结果的手动或使用API。
唯一合理的例外
是创建一个数字指数表上,即:
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。而且您仍然拥有自动数据存储区配额。
但是通过计划1.3.1 SDK,他们引入了可以序列化和保存的游标,以便将来的调用可以从最后一次停止的查询开始。
1000记录限制是Google AppEngine的硬限制。
此演示文稿 http:/ /sites.google.com/site/io/building-scalable-web-applications-with-google-app-engine 说明了如何使用AppEngine有效地翻阅数据。
(基本上通过使用数字id作为键并在id上指定WHERE子句。)
获取超过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
我们在 ModelBase
类中使用的是:
@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个查询限制,而无需考虑它。我认为密钥版本也很容易实现。
class Count(object):
def getCount(self,cls):
class Count(object):
def getCount(self,cls):
"""
Count *all* of the rows (without maxing out at 1000)
"""
count = 0
query = cls.all().order('__key__')
while 1:
current_count = query.count()
count += current_count
if current_count == 0:
break
last_key = query.fetch(1, current_count-1)[0].key()
query = query.filter('__key__ > ', last_key)
return count
entities = []
for entity in Entity.all():
entities.append(entity)
这很简单。请注意,每个实体都有一个RPC,它比以块的形式提取要慢得多。因此,如果您担心性能,请执行以下操作:
如果您的项目少于1M:
entities = Entity.all().fetch(999999)
否则,请使用光标。
还应该注意:
Entity.all().fetch(Entity.all().count())
返回1000最大值,不应使用。
JJG:你的解决方案很棒,但如果你有0条记录会导致无限循环。 (我在本地测试我的一些报告时发现了这一点。)
我修改了while循环的开头,如下所示:
while count % 1000 == 0:
current_count = query.count()
if current_count == 0:
break
将两个查询的内容一起添加:
list1 = first query
list2 = second query
list1 += list2
列表1现在包含所有2000个结果。
建议的解决方案仅在条目按键排序时才有效...如果您先按其他列排序,则仍需使用limit(offset,count)子句,则仍然适用1000条目限制。如果您使用两个请求,它们是相同的:一个用于检索索引(带条件和排序),另一个用于使用第一个结果中的索引子集中的索引(),因为第一个请求不能返回超过1000个键? (如果我们必须按键排序以删除1000个结果限制,那么Google 按键上的查询部分并未明确说明)
这与Gabriel提供的解决方案很接近,但是没有获取它只计算它们的结果:
count = 0
q = YourEntityClass.all().filter('myval = ', 2)
countBatch = q.count()
while countBatch > 0:
count += countBatch
countBatch = q.with_cursor(q.cursor()).count()
logging.info('Count=%d' % count)
完美适用于我的查询,也快速(1.1秒计算67,000个实体)
请注意,查询不能是不等式过滤器或集合,否则游标将无效,您将获得此异常:
AssertionError:没有可用于MultiQuery的游标(使用“IN”或“!=”运算符进行查询)
如果你正在使用NDB:
@staticmethod
def _iterate_table(table, chunk_size=200):
offset = 0
while True:
results = table.query().order(table.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