簡體   English   中英

Django:在同一一對多關系上具有多個聯接的單個查詢

[英]Django: Single query with multiple joins on the same one-to-many relationship

使用Django QuerySet API,如何在相同的兩個表/模型之間執行多個聯接? 出於說明目的,請參見以下未經測試的代碼:

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)

但是事實證明這效率極低,因為我正在處理數百到數千個數據包,除了我想要的緯度和經度字段外,還有許多其他字段。

是否有Django QuerySet調用轉換為有效的SQL查詢,該查詢執行從數據datapacket表到不同行的field表的兩個內部聯接? 我可以使用原始SQL做到這一點,如下所示(假設Django應用程序名為myapp )(再次,未經測試的代碼用於說明目的):

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)

但是本能告訴我,如果不需要,請不要使用低級數據庫API。 支持該問題的可能原因可能是我的SQL代碼可能與Django支持的所有DBM不兼容,或者我覺得我由於誤解SQL命令比誤解Django API更有可能破壞數據庫。電話等

嘗試在Django中執行原始SQL查詢 以及在原始請求中選擇相關

預取原始查詢:

from django.db.models.query import prefetch_related_objects
raw_queryset = list(raw_queryset) 
prefetch_related_objects(raw_queryset, ['a_related_lookup',
'another_related_lookup', ...])

你的例子:

from django.db.models.query import prefetch_related_objects
raw_DataPacket = list(DataPacket.objects.raw)
pp = prefetch_related_objects(raw_DataPacket, ['field_set'])

prefetch_related與原始查詢集的示例:

楷模:

class Country:
    name = CharField()
class City:
    country = models.ForeignKey(Country)
    name = models.CharField()

prefetch_related:

from django.db.models.query import prefetch_related_objects
#raw querysets do not have len()
#thats why we need to evaluate them to list
cities = list(City.objects.raw("select * from city inner join country on city.country_id = country.id where name = 'london'"))
prefetch_related_objects(cities, ['country'])

來自以下來源的信息提供的答案: djangoproject-執行原始查詢 | 相關的Stackoverflow問題 | Google文檔問題

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM