2

私のプログラムでは、非常に大きなテーブル(メモリストレージを超えています)を読み取り、テーブルから読み取っていくつかの作業を行うために次の構造を作成する必要があります。selectをイテレータスタイルに書き直すことは非常に可能ですが、それでも次のような基本構造があります。

    found = True
    start = 0
    batch = 2500
    while found:
        found = False
        for obj in Channel.select().limit(batch).offset(start):
            found = True

            # do some big work...

        start += batch

私がやりたいのは、不格好な状態変数をあまり持ち運ばないものを用意することです。この混乱をクリーンアップする方法のアイデアはありますか?

参考までに-私もこれを試しましたが、これ以上気に入っているかどうかはわかりません。

@staticmethod
def qiter(q, start=0, batch=25000):
    obj = True
    while obj:
        for obj in q.limit(batch).offset(start):
            yield obj
        start += batch
4

2 に答える 2

1

私が見つけた最短のものは次のとおりです。

for start in itertools.count(0, 2500):
    objs = Channel.select().limit(2500).offset(start)
    if not objs:
        break
    for obj in objs:
        # do some big work...

基本的に、それは2つの組み合わせです。

  • イテレータ(標準ライブラリのcountitertoolsパッケージから)は、バッチカウントを最小限に抑え、
  • 別のテストとbreakステートメントを使用して、それから抜け出します。

詳細に:

イテレータは非常に単純です。count無限級数0、2500、5000、7500、...を生成します。このループは決して終わらないので、breakどこかでループから抜け出す必要があります。ここで、ifステートメントが役立ちます。objsが空のリストの場合break、は外側のループが存在します。

于 2013-02-12T21:17:52.753 に答える
0

反復するだけでRAMをすべて使い果たしたくない場合は、QueryResultWrapperの「iterator()」メソッドを確認してください。

たとえば、1,000,000行を超えるデータを反復処理し、シリアル化する必要があるとします。

# let's assume we've got 1M stat objects to dump to csv
stats_qr = Stat.select().execute()

# our imaginary serializer class
serializer = CSVSerializer()

# loop over all the stats and serialize
for stat in stats_qr.iterator():
    serializer.serialize_object(stat)

以下は、ドキュメントへのリンクです。

http://peewee.readthedocs.org/en/latest/peewee/cookbook.html#iterating-over-lots-of-rows

于 2013-02-18T03:26:46.330 に答える