【发布时间】:2011-10-15 11:22:03
【问题描述】:
我正在尝试使用 Django 的 ORM 实现一个简单的三元组。我希望能够搜索任意复杂的三元组模式(例如,就像使用 SparQL 一样)。
为此,我尝试使用.extra() 方法。然而,即使文档提到它理论上可以通过自动为重复的表引用创建别名来处理对同一个表的重复引用,但我发现它在实践中并没有这样做。
例如,假设我的“三重”应用中有以下模型:
class Triple(models.Model):
subject = models.CharField(max_length=100)
predicate = models.CharField(max_length=100)
object = models.CharField(max_length=100)
我的数据库中存储了以下三元组:
subject predicate object
bob has-a hat .
bob knows sue .
sue has-a house .
bob knows tom .
现在,假设我想查询 bob 知道谁有房子的每个人的名字。在 SQL 中,我会这样做:
SELECT t2.subject AS name
FROM triple_triple t1
INNER JOIN triple_triple t2 ON
t1.subject = 'bob'
AND t1.predicate = 'knows'
AND t1.object = t2.subject
AND t2.predicate = 'has-a'
AND t2.object = 'house'
我不完全确定 Django 的 ORM 会是什么样子,尽管我认为它会是这样的:
q = Triple.objects.filter(subject='bob', predicate='knows')
q = q.extra(tables=['triple_triple'], where=["triple_triple.object=t1.subject AND t1.predicate = 'has-a' AND t1.object = 'house'"])
q.values('t1.subject')
很遗憾,此操作失败并显示错误“DatabaseError: no such column: t1.subject”
运行 print q.query 显示:
SELECT "triple_triple"."subject" FROM "triple_triple" WHERE ("triple_triple"."subject" = 'bob' AND "triple_triple"."predicate" = 'knows'
AND triple_triple.object = t1.subject AND t1.predicate = 'has-a' AND t1.object = 'house')
这似乎表明我对 .extra() 的调用中的表参数被忽略了,因为没有在任何地方插入对 triple_triple 的第二次引用。
为什么会这样?使用 Django 的 ORM 引用同一表中记录之间的复杂关系的适当方法是什么?
编辑:我发现这个 useful snippet 通过 .extra() 包含自定义 SQL,以便在模型管理器中使用它。
【问题讨论】:
标签: python sql django sparql django-orm