Django:在同一个一对多关系中具有多个联接的单个查询
使用Django QuerySet API,如何在同一个两个表/模型之间执行多个联接?出于说明目的,请参阅以下未经测试的代码:Django:在同一个一对多关系中具有多个联接的单个查询
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调用转换为执行两个内部联接从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)
但直觉告诉我不要使用低级别的DB API如果我不必这样做。支持这种做法的可能原因可能是我的SQL代码可能与Django支持的所有DBM不兼容,或者我觉得由于误解了SQL命令而导致数据库被贬低的风险比我误解Django API呼叫等。
尝试在django Performing raw SQL queries。以及select related in raw request。
预取和对原始查询:
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', ...])
你举的例子:使用原始的queryset prefetch_related
from django.db.models.query import prefetch_related_objects
raw_DataPacket = list(DataPacket.objects.raw)
pp = prefetch_related_objects(raw_DataPacket, ['field_set'])
例子:
型号:
class Country:
name = CharField()
class City:
country = models.ForeignKey(Country)
name = models.CharField()
prefetch_relate d:从信息从这些来源提供
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 - performing raw queries | Related Stackoverflow Question | Google docs question
同样,我不知道我怎么会用这个来选择从表A的每一行我已经更新了我的问题,以显示我目前如何使用该数据库游标和原始的SQL执行从表B中正好两行。 –
看看[this](https://stackoverflow.com/questions/17375997/django-inner-join-queryset)和[this](https://stackoverflow.com/questions/42984676/django换算换使用-内SQL查询-联接子句)。链接到类似的问题。 – noes1s
@ noes1s你的第一个链接询问如何内从A加盟B,然后从内B到C.加入你的第二个链接问如何标记为非延迟加载只有特定的Django模型领域。这些都不涉及我所要求的。我想从A地加入到B两次:在同一行,在B. –
不同的行,您可以执行原始SQL查询? – noes1s