2012-07-01 3 views
3

EDIT: Пожалуйста, извините меня, поскольку я только что понял, что сделал ошибку с примером ниже. Вот что я хочу достичь:SQLAlchemy - поиск трех таблиц за один раз

Скажем, у меня есть три таблицы, как описано ниже. Когда пользователь вводит запрос, он будет искать все три таблицы для результатов, где имя LIKE% query%, но возвращает только уникальные результаты.

Вот некоторые примеры данных и вывод:

данных:

**Grandchild:** 
id: 1 
name: John 
child_id: 1 

**Grandchild:** 
id: 2 
name: Jesse 
child_id: 2 

**Child:** 
id: 1 
name: Joshua 
parent_id: 1 

**Child:** 
id: 2 
name: Jackson 
parent_id: 1 

**Parent:** 
id: 1 
name: Josie 

Если пользователь ищет «J» будет возвращать два внучат записи: Джон и Джесси. Если пользователь ищет «j, Joshua», он вернет только внуков, которые являются детьми Джошуа - в этом случае, только Джон.

По существу, я хочу искать все записи Grandchild, а затем, если пользователь вводит больше ключевых слов, он будет фильтровать этих внуков на основе их родственного имени дочерней записи. «j» вернет всех внуков, начиная с «j», «j, Josh» вернет всех внуков, начиная с «j», и у которых есть их ребенок LIKE% Josh%.


Итак, у меня есть установки, как это:

Grandchild{ 
    id 
    name 
    child_id 
} 

Child{ 
    id 
    name 
    parent_id 
} 

Parent{ 
    id 
    name 
} 

Внук связан/сопоставляется с ребенком. Ребенок сопоставляется с родителем.

То, что я хочу сделать, это то, как показано ниже, где искать все три базы данных сразу:

return Grandchild.query.filter(or_(
    Grandchild.name.like("%" + query + "%"), 
    Grandchild.child.name.like("%" + query + "%"), 
    Grandchild.child.parent.name.like("%" + query + "%") 
)).all() 

Очевидно, что выше запрос неверен, и возвращает ошибку:

AttributeError: Neither 'InstrumentedAttribute' object nor 'Comparator' object has an attribute 'name' 

Каким будет правильный способ сделать то, что я пытаюсь сделать?

Я запускаю MySQL, Flask-SQLAlchemy (который, я считаю, расширяет SQLAlchemy), Flask.

+0

Кратчайший путь к получению лучший ответ обратно на SQLAlchemy вопросы, подобный этому является предоставление SQL-запроса, который вы надеялись произвести. Понятно, что не у всех это будет на 100% ясным, и они не обязательно будут иметь _have_, чтобы использовать sqlalchemy, но ответ на вопрос «какой sql вы хотите видеть» часто заканчивается ответом на ваш основной вопрос. – cdaddr

+0

Даже если вы не можете рассказать свой запрос в терминах учебника SQL, это поможет описать в предложениях именно то, что вы хотите получить от запроса. Описывая это с помощью неработающего фрагмента кода и «что-то вроде этого», он становится настолько расплывчатым, что мы не можем ответить конкретно. Я не хочу критиковать, только поощряю. – cdaddr

+0

@cdaddr Я обновил вопрос.Надеюсь, это не слишком сложно. – user1492385

ответ

2

Что касается меня, то лучше изменить свою модель данных (если возможно). Вы можете создать самостоятельно ссылочной таблицы «People» так:

People 
{ 
    id, 
    name, 
    parent_id, 
    grandparent_id, 
} 

class People(Base): 
    __tablename__ = "people" 

    id = Column(Integer, primary_key=True, autoincrement=True) 
    name = Column(Unicode(255), nullable=False) 
    parent_id = Column(Integer, ForeignKey('people.id'))  # parent in hierarchy 
    grandparent_id = Column(Integer, ForeignKey('people.id')) # grandparent in hierarchy 

    # relationships 
    parent = relationship("People", primaryjoin="People.parent_id==People.id", 
          remote_side=[id]) 
    grandparent = relationship("People", primaryjoin="People.grandparent_id==People.id", 
           remote_side=[id]) 

Тогда все становится более очевидным:

session.query(People).filter(People.name.like("%" + query + "%")) 
+0

Я рассматривал это, но тогда мне пришлось бы хранить в два раза больше данных. Хмм ... – user1492385

+1

Единственные дополнительные данные, которые вы будете хранить, - это Nulls для людей, у которых нет родителей или бабушек и дедушек. –

+0

Извините, пожалуйста, прочитайте обновленный вопрос. Я не очень хорошо себя объяснил. – user1492385

Смежные вопросы