4

私はreddit/hackernewsが具体的に(これは多くの主要なサイトで一般的なアプローチのようです)彼らの「新しい」リストを処理する方法に似たものを探しています。次のように機能するようです。

  • 新しいリンクが送信されると、特定の数の最新のエントリが取得されます
  • これらのクエリはPER_PAGE#で分割され、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)

4

2 に答える 2

4

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])

これにより、データベースへの複数のクエリが発生することに注意してください。itertools.izip_longest()または、関数を使用して50 個のアイテムのグループを生成することもできます。

from itertools import izip_longest

for chunkOf50Results in izip(*[q.yield_per(50)]*50):
     CachedChunk += 1
     cache.set(CachedChunk, chunkOf50Results)

行のプリフェッチをバッチサイズに制限してい.yield_per(50)たので、バッチごとに必要以上にプリフェッチすることはありません。

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、バッチ サイズに合わせて値が埋め込まれていることに注意してください。

于 2012-08-24T16:13:57.163 に答える
2

解決策は、ドキュメントに記載されてitertools.izip_longestいるトリックで使用することです

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)

これにより、データベースへの1 回のトリップで最大 1000 件の記事取得され、それらを 50 件のバッチに分割してキャッシュすることができます。

于 2012-08-24T16:34:39.853 に答える