展平使用 select_related() 和完全连接的 Django 查询集
Flatten Django Queryset that is using select_related() and full join
我的目标是联合两个查询集,但是,它们只匹配第一个查询集与其外键连接后的列 table。让我解释。假设我有三个这样的模型:
Models.py
class Data(models.Model):
name = models.TextField()
extra_data = models.OneToOneField(Extra, on_delete=models.CASCADE)
class Extra(models.Model):
age = models.IntegerField()
class FullData(models.Model):
name = models.TextField()
age = models.IntegerField()
那么我正在尝试做这样的事情:
data = Data.objects.select_related()
fullData = FullData.objects.all()
queryset = data.union(fullData)
这 return 是一个错误:
django.db.utils.OperationalError: SELECTs to the left and right of UNION do not have the same number of result columns
这里的两个问题是:
如果 Extra
table 中没有相关行,data
不会获取列
- select_related 中的列只能通过执行
data.extra_data.age
访问,这意味着并集的左侧不会有相同数量的列。
我想使用 django,但它没有给我与查询相同的结果:
SELECT *
FROM Data LEFT JOIN Extra on Data.extra_data = Extra.id
请注意我使用的是 sqlite,这就是为什么上面的查询是用 LEFT JOIN 编写的。
关于如何让数据中的行的 select_related() 到 return 空值的任何想法,这些行在 Extra 中没有一对一的行,并将其展平,以便列匹配 FullData 查询集?
你可以这样做:
data = Data.objects.annotate(age=F('extra__age')).all()
那么你可以这样访问年龄
data[0].age
我的目标是联合两个查询集,但是,它们只匹配第一个查询集与其外键连接后的列 table。让我解释。假设我有三个这样的模型:
Models.py
class Data(models.Model):
name = models.TextField()
extra_data = models.OneToOneField(Extra, on_delete=models.CASCADE)
class Extra(models.Model):
age = models.IntegerField()
class FullData(models.Model):
name = models.TextField()
age = models.IntegerField()
那么我正在尝试做这样的事情:
data = Data.objects.select_related()
fullData = FullData.objects.all()
queryset = data.union(fullData)
这 return 是一个错误:
django.db.utils.OperationalError: SELECTs to the left and right of UNION do not have the same number of result columns
这里的两个问题是:
-
如果
data
不会获取列- select_related 中的列只能通过执行
data.extra_data.age
访问,这意味着并集的左侧不会有相同数量的列。
Extra
table 中没有相关行,我想使用 django,但它没有给我与查询相同的结果:
SELECT *
FROM Data LEFT JOIN Extra on Data.extra_data = Extra.id
请注意我使用的是 sqlite,这就是为什么上面的查询是用 LEFT JOIN 编写的。
关于如何让数据中的行的 select_related() 到 return 空值的任何想法,这些行在 Extra 中没有一对一的行,并将其展平,以便列匹配 FullData 查询集?
你可以这样做:
data = Data.objects.annotate(age=F('extra__age')).all()
那么你可以这样访问年龄
data[0].age