2017-07-12 5 views
1

大きなクエリーセットからすべてのオブジェクトを削除しようとしています。ここに私のmodels.pyはDjango 1.10大きなカスケードクエリーセットを削除する

from __future__ import unicode_literals 
from django.contrib.auth.models import User 
from django.db import models 


class Fund(models.Model): 

    name = models.CharField(max_length=255, blank=False, null=False) 
    start_date = models.DateField(default=None, blank=False, null=False) 

    def __unicode__(self): 
     return self.name 


class FundData(models.Model): 

    fund = models.ForeignKey(Fund, on_delete=models.CASCADE) 
    date = models.DateField(default=None, blank=False, null=False) 
    value = models.FloatField(default=None, blank=True, null=True) 

    def __unicode__(self): 
     return "{} --- Data: {} --- Value: {} ".format(str(self.fund), str(self.date), str(self.value)) 

あるしかし、私は、クエリがあまりにも多くの時間とMySQLを取るすべてのレコードを削除しようとすると、タイムアウトしています。

Fund.objects.all().delete() 
  • ビュー内でこの操作を管理するための最良の方法は何ですか?
  • 端末からdjangoコマンドを呼び出す方法がありますか?すべての

答えて

1

まずあなたが.delete()が遅くなることが理由settings.py

DATABASES = { 
    'default': { 
     ... 
     OPTIONS = { 
      'connect_timeout': 5, # your timeout time 
     } 
     ... 
    } 
} 

の理由をedditingでのMySQLのタイムアウト時間を変更することができます:

  1. Djangoは適切にカスケード削除機能を確保するために持っています。それはあなたのモデルに外部キーを探すために持ってい
  2. ジャンゴ何とか前処理するために持っており、あなたのモデルのための信号をポストセーブ
  3. 、あなたのモデルがカスケード削除または任意の信号にしていないことが確実な場合

あなたは次のようにプライベート_raw_deleteを使用しようとすることができ、処理される:

queryset._raw_delete(queryset.db) 

あなたはそれについての詳細here

+0

私のモデルにはon_delete = models.CASCADEがあります。すべてのファンドの削除関連するすべてのファンドデータ(各ファンドの数千)も削除します。カスケードの保護はありません。 ? – Andrea

+0

私は本当にconnect_timeoutの変更が役立つかどうかは分かりません。 mysqlのドキュメントから: "不正なハンドシェイクで応答する前に、mysqldサーバが接続パケットを待つ秒数。デフォルト値は10秒です。クライアントがMySQLサーバとの接続が失われたというエラーが頻繁に発生した場合は、 「XXX」、「system」にあります。 – Andrea

+0

@アンドレア「カスケードの保護がない」とは、単に削除されないことを意味します。あなたは正確なトレースバックを貼り付けていないので、あなたが持っているタイムアウトを言うのは難しいです。これがhttps://dev.mysql.com/doc/refman/5.7/en/gone-away.htmlに役立つとは思いませんか? – pythad

0

最後に、私はすべてのカスケードオブジェクトのブレアを削除するには、簡単な解決策を持って見つけることができますキングオブジェクトを削除することを優先してマクロ削除操作をダウンさせる。それは実際に長い操作(何千ものオブジェクトの各オブジェクトの約1秒)なので、私はそれをセロリの作業員に割り当てました。ゆっくりだけど安全だと思います。

@shared_task 
def reset_funds(): 
    for fund in Fund.objects.all(): 
     print "Delete Fund: {}".format(fund.name) 
     fund.delete() 
    return "All Funds Deleted!" 
関連する問題