私はテーブルが何百万ものレコードを持っているDjangoモデルを持っています。私はシェルのテーブル内のすべてのレコードの緊急保守をやろうとしていますが、システム上のメモリを完全に使い果たすことなくMyModel.objects.all()
を実行できません。メモリを使い果たすことなくDjangoの大きなテーブルを反復するには?
でもpass
が私のプロセスを殺し、OOMキラーが呼び出されます:
for ii in MyModel.objects.all():
pass
DjangoのQuerySet
はすべてのリストを構築することにより、その「結果キャッシュ」を構築しようとしているので、理由がありますここでの私の記録、の:
# django/db/models/query.py
def _fetch_all(self):
if self._result_cache is None:
self._result_cache = list(self.iterator()) # <<<< this guy!
if self._prefetch_related_lookups and not self._prefetch_done:
self._prefetch_related_objects()
しかし、私のマシンはメモリ内のリスト全体を保持することはできません。
このような大きなテーブルでは、実際のアプリケーションでは恐ろしいアイディアになるので、この問題の範囲は限られています(メンテナンス作業)が、時々起こります。
うーん、これは結果キャッシュを回避するように見えるんが、私はまだ( 'ジャンゴ/ DB /バックエンド/ utils.py'でCursorWrapper.execute''で)、メモリが不足しています。..だから私は結果のキャッシュが私を殺す唯一の事ではないと思う、それはポストグルから取り出されたレコードの真の数である... – mgalgs
それは私を驚かせるが、私はDjangoがカーソルとレコードをメモリにプルする場所。実際のモデルインスタンスなしでメンテナンスを行うことができたり、生のデータベースレコードをモデルに変換しようとしている場合、この回答からリンクされたブログ記事の1つが役立つでしょうか? http:// stackoverflow。com/questions/18381695/get-database-cursor-from-djangos-rawqueryset https://docs.djangoproject.com/en/1.10/topics/db/sql/#connections-and-cursors for Djangoドキュメント。 –
私はモデルインスタンス上のメソッドを呼び出していますが、私はそれを完全に取り除くことができます。これは避けたい作業でした。こことそこの奇妙なメンテナンスのための大したことではありません。私は、生のデータベースレコードに落とさずにこれを行う良い方法があることを期待していました。しかたがない。 – mgalgs