DjangoのORMを使用して簡単なtriplestoreを実装しようとしています。任意の複雑なトリプルパターン(たとえば、SparQLの場合と同じように)を検索することができるようにしたいと思います。DjangoのORM Extra()を使用して重複テーブルを含める
これを行うには、.extra()メソッドを使用しようとしています。しかし、ドキュメントでは、論理的には、重複したテーブル参照のエイリアスを自動的に作成することによって、同じテーブルへの重複した参照を処理することができると言われていますが、実際にはそうはしません。
class Triple(models.Model):
subject = models.CharField(max_length=100)
predicate = models.CharField(max_length=100)
object = models.CharField(max_length=100)
と私は、次のトリプルは私のデータベースに保存されています:たとえば
が、私は私の「トリプル」アプリで、以下のモデルを持っていると言う今subject predicate object
bob has-a hat .
bob knows sue .
sue has-a house .
bob knows tom .
、私が欲しいと言いますみんなの名前を照会することができます。 SQLでは、私は単純にやると思います。残念ながら
q = Triple.objects.filter(subject='bob', predicate='knows')
q = q.extra(tables=['triple_triple'], where=["triple_triple.object=t1.subject AND t1.predicate = 'has-a' AND t1.object = 'house'"])
q.values('t1.subject')
:私はそれはのラインに沿ったものだと思うが、
SELECT t2.subject AS name
FROM triple_triple t1
INNER JOIN triple_triple t2 ON
t1.subject = 'bob'
AND t1.predicate = 'knows'
AND t1.object = t2.subject
AND t2.predicate = 'has-a'
AND t2.object = 'house'
私は、これはDjangoのORMとどのように見えるかを完全にはよく分かりません、これはエラーで失敗しない "DatabaseError:そのようなコラム:t1.subject" 印刷q.queryを実行
を示しています
SELECT "triple_triple"."subject" FROM "triple_triple" WHERE ("triple_triple"."subject" = 'bob' AND "triple_triple"."predicate" = 'knows'
AND triple_triple.object = t1.subject AND t1.predicate = 'has-a' AND t1.object = 'house')
は、どこにも挿入されたtriple_tripleへの2番目の参照がないので、.extra()の呼び出しでテーブルのparamが無視されていることを示すようです。
どうしてですか? DjangoのORMを使用して同じテーブル内のレコード間の複雑な関係を参照する適切な方法は何ですか?
EDIT:これは、モデルマネージャ内で使用できるように、.extra()を使用してカスタムSQLを含めるためにこのが見つかりました。
ありがとうございました。奇妙なのは、2番目のテーブルがWHERE句でフィルタリングされるときにクエリが中断されるため、SELECTで参照されなかったために追加のテーブルが削除されるということです。考えられるバグ? – Cerin
@ Cerin:これはバグだとは思わないが、これは、where paramを使用してより多くの条件を設定し、返されたクエリーセットに列を追加することを選択するという汚い解釈です。 –
@ Tommaso:私の主張は、各テーブルから少なくとも1つの列を選択しない限り、複数のテーブルを使用できないようです。これは理にかなっていません。なぜなら、私はいつもJOINしたい各テーブルの列をSELECTしたいと思うわけではないからです。だから私はこれがバグか、あまり設計されていない機能だと思うのです。 – Cerin