Я пытаюсь реализовать простое хранилище троек с использованием ORM Django. Я хотел бы иметь возможность искать произвольно сложные тройные шаблоны (например, как вы это делаете со 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 .
Теперь, допустим, я хочу запросить имена всех, кого знает Боб, у кого есть дом. В 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'
Я не совсем уверен, как это будет выглядеть с ORM Django, хотя я думаю, что это будет примерно так:
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 : нет такого столбца: t1.subject "
Запуск печати 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 где угодно.
Почему это происходит? Как лучше всего ссылаться на сложные отношения между записями в одной таблице с помощью ORM Django?
РЕДАКТИРОВАТЬ: Я нашел этот полезный фрагмент для включения пользовательского SQL через .extra (), чтобы его можно было использовать внутри модельный менеджер.