Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使用Flask/SQLAlchemy将返回结果的数量限制为仅1000个最新条目?_Python_Caching_Sqlalchemy_Flask_Flask Sqlalchemy - Fatal编程技术网

Python 如何使用Flask/SQLAlchemy将返回结果的数量限制为仅1000个最新条目?

Python 如何使用Flask/SQLAlchemy将返回结果的数量限制为仅1000个最新条目?,python,caching,sqlalchemy,flask,flask-sqlalchemy,Python,Caching,Sqlalchemy,Flask,Flask Sqlalchemy,我正在寻找类似reddit/hackernews(这似乎是许多主要网站的常用方法)处理其“新”列表的方式。它似乎是这样工作的: 提交新链接时,会抓取一定数量的最新条目 这些查询被每个页面分割,并缓存为cachekey=newestPage1,2,3,4 单击下一个/上一个按钮加载下一个/上一个缓存键 我的问题是:很难找到SQLalchemy/flask SQLalchemy代码,以便只查询最新条目的固定数量 我怎么说: q = PostDB.query(order_by('creation_

我正在寻找类似reddit/hackernews(这似乎是许多主要网站的常用方法)处理其“新”列表的方式。它似乎是这样工作的:

  • 提交新链接时,会抓取一定数量的最新条目
  • 这些查询被每个页面分割,并缓存为cachekey=newestPage1,2,3,4
  • 单击下一个/上一个按钮加载下一个/上一个缓存键
我的问题是:很难找到SQLalchemy/flask SQLalchemy代码,以便只查询最新条目的固定数量

我怎么说:

q = PostDB.query(order_by('creation_time').desc()).limit(1000)
for chunkOf50Results in q:
  cache.set(CachedChunk+=1, chunkOf50Results)

如果在SQLAlchemy中切片查询,它会自动限制获取的数据库结果集:

limitedQuery = q[:50]
如果您要先获得计数,您可以轻松地循环分组响应:

count = q.count()
for chunkstart in xrange(0, count, 50):
    CachedChunk += 1
    chunkend = min(chunkstart + 50, count)
    cache.set(CachedChunk, q[chunstart:chunkend])
请注意,这确实会导致对数据库的多个查询。或者,您可以使用生成50个项目的组:

from itertools import izip_longest

for chunkOf50Results in izip(*[q.yield_per(50)]*50):
     CachedChunk += 1
     cache.set(CachedChunk, chunkOf50Results)
我曾经将行预取限制为batchsize,这样就不会预取超过每个批所需的量

izip_longest(*[iterable]*n)
技巧可以从基本迭代器中获得大小为
n
的组:

>>> import itertools
>>> list(itertools.izip_longest(*[iter(range(7))]*3))
[(0, 1, 2), (3, 4, 5), (6, None, None)]
请注意,最后一批用
None
值填充,以填充到批大小。

解决方案是使用技巧


这将导致one访问数据库,获取多达1000篇文章,然后让您将它们分成50个批次并缓存它们。

迫不及待地想尝试一下。如果每次发布新条目(更新区块)时都运行此操作,那么当有数百万行要计数时,每次q.count()不是都会变成一个巨大的操作吗?@chrickso:数据库应该优化这种情况。行计数应该很便宜(足够了)。遗憾的是,情况并非总是如此,这取决于所使用的数据库。MySQL尤其臭名昭著,因为在某些情况下每次调用count()时都会扫描整个表。还有其他不依赖“计数”的分页方案,但这些方案显然不能提供可用的总页数。@zzzeek:无论如何,我越来越倾向于
izip_longest
方法。:-)感谢MySQL扫描案例,我很高兴地说,我通常不需要使用该数据库。我如何确保获取的1000个条目是最新的条目,而不是它在达到1000个之前收集的某个随机批次?好吧,我试图理解这里的操作顺序。当我执行q=PostDB.query(order_by('creation_time').desc()).limit(1000)时,我认为这将获得前1000行,然后按创建时间对它们进行排序,而不是确保这1000行是最新的1000@chrickso-不,它按创建时间对整个表进行排序(从最新到最旧),然后从列表中删除前1000个。(事实上,大多数数据库都比这聪明一点,如果可以的话,它们会使用索引来避免对所有内容进行排序)。
q = PostDB.query(order_by('creation_time').desc()).limit(1000)

query_iterators = [iter(q)] * 50

for CachedChunk, chunk_of_50 in enumerate(izip_longest(*query_iterators)):
     cache.set(CachedChunk, chunk_of_50)