Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/laravel/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql Django中具有非外键联接的约束_Sql_Django - Fatal编程技术网

Sql Django中具有非外键联接的约束

Sql Django中具有非外键联接的约束,sql,django,Sql,Django,在我的数据库中,我有一对表(tableA和tableB),它们都有外键引用tableC中的同一列ID。我能够使用的SQL是 SELECT * FROM tableA INNER JOIN tableB on tableA.ID=tableB.ID WHERE tableB.year=2011 询问 SELECT * FROM tableA INNER JOIN tableB on tableA.ID=tableB.ID AND tableB.year=2011 做了同样的事 在Django中

在我的数据库中,我有一对表(
tableA
tableB
),它们都有外键引用
tableC
中的同一列
ID
。我能够使用的SQL是

SELECT *
FROM tableA
INNER JOIN tableB on tableA.ID=tableB.ID
WHERE tableB.year=2011
询问

SELECT *
FROM tableA
INNER JOIN tableB on tableA.ID=tableB.ID AND tableB.year=2011
做了同样的事

在Django中,我试图用代码来实现这一点

subquery=tableB.objects.filter(year=2011).values_list(id, flat=True)
results=tableA.objects.filter(id__in=list(subquery))

正如报告中所建议的那样。我知道这有点不同,因为它只返回
tableA
中的列,但我还是只使用这些列。Django代码似乎很慢,我想部分原因是对
tableA
的每一行进行集合成员测试,这非常大。在Django中有没有一种不用原始SQL(如果需要的话,我当然可以使用原始SQL)就可以更快地实现这一点的方法?

您的模型似乎不太“Django”友好。您是否使用一对一关系,并且您的表pk是外键?(如果不是,请在问题中张贴您的模式)。Django希望表(模型)主键是唯一的自动递增整数,而不是外键

django明智的做法是:

类表C(models.Model):
name=models.CharField(最大长度=1000)
类别表A(models.Model):
表C=模型。OneToOneField(表C)
类别表B(型号.型号):
表C=模型。OneToOneField(表C)
年份=型号。整型字段()
请注意,所有字段都有一个(隐式)id字段,它是表的主键。现在执行:

TableA.objects.filter(tablec\uuuu tableb\uuuu year\uuuuu exact=2011)
实际上,您可以使用外键作为主键:

类表C(models.Model):
name=models.CharField(最大长度=1000)
类别表A(models.Model):
tablec=models.OneToOneField(tablec,primary\u key=True,db\u column='id')
类别表B(型号.型号):
tablec=models.OneToOneField(tablec,primary\u key=True,db\u column='id')
年份=型号。整型字段()

并执行相同的查询。但是,这可能会在以后给您带来更多的问题(“无保修”)。

它的速度很慢,因为它正在创建一个可能类似于

SELECT * FROM TableA WHERE ID IN (SELECT ID FROM TableB WHERE year=2011)

就像@Udi所说的,如果你能通过添加外键来“django”使模型更具规模,你会过得更好。否则,使用RawSQL。这就是它的用途。

不要将
子查询
转换为列表。如果您只是这样做:

results=tableA.objects.filter(id__in=subquery)

Django应该足够聪明,可以实际执行一个子查询,而不是两个单独的查询。

这可能是一个愚蠢的问题,但究竟是什么-你正在运行Django的最新版本吗?我使用的是Django 1.3,而不是开发版本,如果你问的是这个问题的话。如果你还没有,跳转到irc.freenode.net上的#django频道-那里有很多非常棒的开发人员-将url传递给他们到这个页面。我忘了提到,我使用的是MySQL数据库,我链接到的文档页面说MySQL没有很好地优化嵌套查询,使用两个查询会更快。谢谢你的帮助。我会这样做,但我的模型实际上来自其他来源的数据,我只是使用Django作为该数据的接口。另外,如果不进行非规范化,我想不出任何方法可以将表中的关系转换为一对一关系,我不希望这样做。我相信您仍然可以使用一对多来完成上述操作,并避免使用原始sql。在某些情况下,跨越三个表的外键-外键联接可能比使用子查询更快。