Включая Дублирование таблиц с использованием Django ORM Extra ()

Я пытаюсь реализовать простое хранилище троек с использованием 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 (), чтобы его можно было использовать внутри модельный менеджер.

8
задан Cerin 29 July 2011 в 18:18
поделиться