2012-03-19 1 views
3

私の質問をもっと分かりやすくするために、ここに例があります。Django:SQLと同じものを実現することは可能ですか?

二つのモデルがあります:

class A(models.Model): 
    name = models.CharField(max_length = 10) 

class B(models.Model): 
    a = models.ForeignKey(A) 
    name = models.CharField(max_length = 10) 

は、したがって、この例では、AとBは、1対多の関係です。さて、私は次のクエリをしたいとしましょう:少なくとも1つのBを子として持つAを見つける。 SQLでは、明らかにexists節を使うべきです。 ormでまったく同じことを達成することは可能ですか?

私はそれについていくつかの調査をしましたが、SQLクエリに完全に一致するものは見つかりませんでした。最も近い解決策は次のようなものです:

A.objects.filter(b__pk__gt = 0).distinct() 

しかし、それはsqlのexist節からまだ遠く、存在するほど効率的でないかもしれません。

答えて

1

以下は、1つまたは複数の関連するBの持っているすべてのA秒を選択します:

A.objects.filter(b__isnull=False) 

b__isnull=Trueへの切り替えは、それらに関連したB秒を持っていないだけA Sを選択します。

+0

したがって、b__isnull = Falseの場合、もはや別名を追加する必要はありません。それはsqlの正当な存在節ですか? –

+0

あなたは区別する必要はありませんが、どのクエリが正確に実行されるか分かりません。しかし、あなたはDjango ORMを使うのが一番です。それ以外の場合は、 'raw'で必要なSQLを直接使用してください。 –

+0

あなたが最適化するために外出する前に、正しい答えを得てください。あなたが本当にORMのSQLでカバーの下を見なければならないなら、 'import django; django.db.connection.queries'を './manage.py shell'から削除します。 – istruble

1

実際には(私があなたがやろうとしていることを誤解していない場合)プレーンなSQLを使うと、単純な左の結合がEXISTING節の代わりに行く方法になります。

あなたのクエリセットは.distinctせずに正常に動作します()

あなたは何が起こっているのを見ると、実際にEXPLAINの代わりに、/ ANALYZEを実行できるように、私は、ORMが生成するDjangoのクエリを見てすることができお勧めパフォーマンスを推測する。

クエリーセットのクエリー属性から未処理クエリーを表示したり、さらにはdjangoデバッグツールバーをインストールして、特定のリクエストのすべてのクエリーを見ることができます。

+0

+1デバッグツールバーの場合。クエリを見ると、 'A.objects.exclude(b__isnull = True)'がLEFT OUTTER JOINを実行し、 '... filter(b__isnull = False)'がINNER JOINを実行することがわかります。 – istruble

+0

@istruble実際には、この種のクエリのために参加する方法です。 –

+0

申し訳ありません。しかし、私はここにあなたの存在とシンプルな左に参加するコメントに同意する必要があります。私の例は、単にB子を持つAを探しているだけです。私はBにフィルターを付けていません。それが存在するか、その置き換えは自然な選択です。 –

関連する問題