2015-09-10 23 views
5

通常のクエリーセットまたはイテレータークエリーセットメソッドは、データセット全体を評価してワンショットで返します。クエリーセットデータを1つずつ取得する

例えば、これを取る。どちらの方法で

my_objects = MyObject.objects.all() 
for rows in my_objects:   # Way 1 
for rows in my_objects.iterator(): # Way 2 

質問

をすべての行がsingle-go.Isクエリセット行ができることdjagoの任意の方法でフェッチされデータベースから1つずつ取り出されます。

なぜこの奇妙な要件

現時点で私のクエリがフェッチすることができますn行を言いますが、いつか私がPython and Django OperationalError (2006, 'MySQL server has gone away')を取得します。

ので、このための回避策を持っているために、私は現在、そこに任意のネイティブまたは作り付けの方法があるか、最初の場所でも、論理的な、私の質問の場合logic.Soは思っていたループ奇妙なwhileを使用しています! :)

答えて

2

私はあなたがlimit your query setを探していると思います。上記のリンクから

引用:

結果、特定の数にあなたのクエリセットを制限するために、Pythonの配列スライス表記のサブセットを使用してください。これは、SQLのLIMIT句およびOFFSET句に相当します。言い換えれば

、あなたは、ループもちろん

cnt = MyObject.objects.count() 
start_point = 0 
inc = 5 
while start_point + inc < cnt: 
    filtered = MyObject.objects.all()[start_point:inc] 
    start_point += inc 

..上で、あなたがそれらを必要とするスライスを取るあなたはこの多くを扱うエラーする必要があるかもしれない可能回数で起動した場合..

+0

私は、もちろん、これは間違いなく周り掘っている間、私が考えた一つの方法です:) – Sayse

+0

好ましいであろうこと、あなたはここで、実際の問題を修正するに見ていると仮定していますneat.I午前に見えます制限なしでジャンゴ自体に他の*ネイティブ*の方法があるのだろうか?実際の問題としては、それはdjangoのバージョンに関連していますが、プロジェクト全体がそれに基づいているので、私はそれについて何もできません..... – NoobEditor

+0

@NoobEditor - これはネイティブと同じだと思います。これは、実行するクエリが変更されるためです。 dbに対して複数のクエリを実行しますが、N個の結果のみを一度に返します。もう1つのオプションは、実際に返す必要があるものを見て、それらのフィールドを返すために 'values'を使うことです。 (私は私の例で一度に5を取り出していますが、これは一度に多くのことを処理できると思っています) – Sayse

2

行単位で取得する方が悪い可能性があります。私はused this django snippet(私の仕事ではありません)を非常に大きなクエリーセットで成功させました。それはメモリを食べず、接続が遠ざかることもありません。ここで

は、そのリンクからの抜粋です:

import gc 

def queryset_iterator(queryset, chunksize=1000): 
    ''''' 
    Iterate over a Django Queryset ordered by the primary key 

    This method loads a maximum of chunksize (default: 1000) rows in it's 
    memory at the same time while django normally would load all rows in it's 
    memory. Using the iterator() method only causes it to not preload all the 
    classes. 

    Note that the implementation of the iterator does not support ordered query sets. 
    ''' 
    pk = 0 
    last_pk = queryset.order_by('-pk')[0].pk 
    queryset = queryset.order_by('pk') 
    while pk < last_pk: 
     for row in queryset.filter(pk__gt=pk)[:chunksize]: 
      pk = row.pk 
      yield row 
     gc.collect() 
+0

あなたのURLは仲間を開いていません! – NoobEditor

+0

@ e4c5:http://https//djangosnippets.org/snippets/1949/ ..にリダイレクトされていますが、ページが表示されていません。 :D – NoobEditor

+0

スニペットをコピーして貼り付けて回答を更新しました。 – e4c5

1

解決するために(2006年、「MySQLサーバが立ち去りました」)問題、あなたのアプローチは、その論理的ではありません。各エントリのデータベースをヒットすると、将来的にアプリケーションの使用状況が増えるにつれて問題を引き起こすクエリの数が増えます。 結果のすべての要素を反復した後にmysql接続を終了してから、別のクエリを作成しようとすると、djangoは新しい接続を作成します。

from django.db import connection: 
connection.close() 

Refer this for more details

+0

の問題は、クエリーセットをフェッチしている間に 'connection'がダンプされているということです。したがってエラーです。私が閉じて新しい接続を開始しても、同じ問題が再発します。助け無し! :\ – NoobEditor

関連する問題