Django QuerySet APIを使用して、同じ2つのテーブル/モデル間で複数の結合を実行するにはどうすればよいですか?説明のために、次のテストされていないコードを参照してください:私は特定の名前付きフィールドを持つデータパケットのリストを取得したいDjango:同じ1対多の関係で複数の結合を持つ単一のクエリ
class DataPacket(models.Model):
time = models.DateTimeField(auto_now_add=True)
class Field(models.Model):
packet = models.ForeignKey(DataPacket, models.CASCADE)
name = models.CharField(max_length=25)
value = models.FloatField()
。私はこのような何か試してみました:
pp = DataPacket.prefetch_related('field_set')
result = []
for p in pp:
o = {
f.name: f.value
for f in p.field_set.all()
if f.name in ('latitude', 'longitude')
}
o['time'] = p.time
result.append(o)
をしかし、私は私が欲しい緯度と経度のフィールド以外の他の分野の多くのパケットの数百〜数千で働いているので、これは非常に非効率的であることが証明されました。
datapacket
テーブルから異なる行のfield
テーブルへの2つの内部結合を実行する効率的なSQLクエリに変換するDjango QuerySet呼び出しがありますか?
from django.db import connection
with connection.cursor() as cursor:
cursor.execute('''
SELECT p.time AS time, f1.value AS lat, f2.value AS lon
FROM myapp_datapacket AS p
INNER JOIN myapp_field as f1 ON p.id = f1.packet_id
INNER JOIN myapp_field as f2 ON p.id = f2.packet_id
WHERE f1.name = 'latitude' AND f2.name = 'longitude'
''')
result = list(cursor)
をしかし本能があれば、低レベルのDB APIを使用しないように私に語った次のように私は(Djangoアプリケーションがmyapp
命名されたと仮定した場合)(説明のために、再び、未テストコード)、生のSQLでそれを行うことができます私はそうする必要はありません。私のSQLコードがDjangoがサポートしているすべてのDBMと互換性がないかもしれない、あるいは私がDjango APIを誤解しているよりもSQLコマンドを誤解してデータベースを壊す危険があるように感じるかもしれない電話など
[this](https://stackoverflow.com/questions/17375997/django-inner-join-queryset)と[this](https://stackoverflow.com/questions/42984676/django)をご覧ください。 -equivalent-for-sql-query-using-inner-join-clause)を使用します。同様の質問へのリンク。 – noes1s
@ noes1s最初のリンクは、AからBへの内部結合の方法と、BからCへの内部結合の方法を尋ねています.2番目のリンクは、非遅延読み込みの特定のDjangoモデルフィールドのみをマークする方法を尋ねます。これらのどちらも私が求めているものには触れません。私はAからBへ2回参加したい:Aの同じ行、Bの異なる行 –
生のSQLクエリを実行できましたか? – noes1s