12

django QuerySet API を使用して、M2M リレーションチップ全体で完全外部結合のクエリを作成するにはどうすればよいですか?

サポートされていない場合は、これを行うための独自のマネージャーを作成するためのヒントを歓迎します。

追加するために編集: @S.Lott: 啓発に感謝します。OUTER JOIN の必要性は、アプリケーションに由来します。まだ不完全であっても、入力されたデータを示すレポートを生成する必要があります。結果が新しいクラス/モデルになるという事実を知りませんでした。あなたのヒントは私をかなり助けます。

4

2 に答える 2

17

Djangoは、通常のSQLの意味での「結合」をサポートしていません。オブジェクトナビゲーションをサポートしています。

リレーショナル結合(内部または外部)は、エンティティの新しい「クラス」を作成することに注意してください。Djangoに定義がないもの。したがって、返されるもののクラス定義がないため、適切な「結果セット」はありません。最善の方法は、欠落している組み合わせに対してNoneがパックされるタプルを定義することです。

左(または右)の外部結合は次のようになります。これは、関連するエンティティのセットが関連付けられているサブセットと持たないサブセットの2つの互いに素なサブセットを作成します。

for obj in Model1.objects.all():
    if obj.model2_set().count() == 0:
        # process (obj, None) -- no Model2 association
    else:
        for obj2 in obj.model2_set.all():
            # process (obj, obj2) -- the "inner join" result

「完全な」外部結合は、関係のない残りのアイテムの結合です。

for obj2 in Model2.objects.all():
    if obj2.model1_set().count() == 0:
        # process (None, obj2) -- no Model1 association

問題は常に、オブジェクトの3つの異なるサブセットのこの奇妙なコレクションでどのような処理を行っているかということです。

オブジェクトデータベースのポイントは、オブジェクトとそれに関連するオブジェクトに処理を集中させることです。

「リレーショナル結合」と呼ばれる独特のコレクションは、元のオブジェクトモデルには含まれていません。これは、2つ(またはそれ以上)の元のオブジェクトから構築された新しいクラスのオブジェクトです。

さらに悪いことに、外部結合は、複数のサブクラス(内部結合、左外部結合、および右外部結合)を持つコレクションを作成します。そのコレクションはどういう意味ですか?

待ってください、それは悪化する可能性があります。処理に欠落している属性のチェックが含まれている場合(つまり、基本的にオブジェクトが関連付けられていないアイテムをif someObj.anObj2attribute is None探しています。うーん...ステートメントを使用してフィルタリングするためだけに、それらを外部結合に配置したのはなぜですか?個別のクエリと各サブセットを適切に処理しますか?Model1Model2if


編集:「未完了」ステータスを表示している場合、それは外部結合ではありません。それははるかに簡単です。テンプレートを表示するには、ビュー関数に1つ(または2つ)の個別のコレクションを作成する必要があります。

まず、外部キーの有無ではなく、ステータスコードを使用する必要があります。オプションの外部キーには「理由」がありません。それらは存在するか存在しないかのどちらかです。ステータスコードは、有用な意味の色合いを提供できます(「不完全」、「エラー」、「壊れた」、「該当なし」、「削除予定」など)。

errorList1 = Model1.objects.filter( status="Incomplete" )
errorList2 = Model2.objects.filter( status="Incomplete" )

これらの2つは、完全な外部結合の2つの非結合部分です。次に、これら2つのエラーリストを、適切な列タイトルとステータスコード、およびすべてとともにテンプレートに表示できます。

それらを単一のテーブルに入れて、人々が以前見ていた古い完全な外部結合レポートを模倣することもできます。

<table>
    <tr><th>Model1</th><th>Model2</th></tr>
    {% for e1 in errorList1 %}
    <tr><td>e1</td><td>NULL</td></tr>
    {% endfor %}
    {% for e2 in errorList2 %}
    <tr><td>NULL</td><td>e2</td></tr>
    {% endfor %}
</table>

完全な外部結合レポートのように見えます。完全な外部結合なし。

于 2008-10-31T10:23:19.783 に答える
1

私が一緒に働いている人の 1 人である Colin は、Django でカスタム結合を行うことについて、しばらく前に投稿を書きました。

http://www.caktusgroup.com/blog/2009/09/28/custom-joins-with-djangos-queryjoin/

そこで役立つものが見つかるかもしれません!

于 2010-03-12T01:14:01.783 に答える