Запрос (объект, который я ищу), который состоит из пользователя, которому назначается роль, представленного указанным запросом. См. ниже:

class Request(db.Model):
    __tablename__ = 'requests'
    id = Column(Integer, primary_key=True)
    user = Column(Integer, ForeignKey("users.id"), nullable=False)
    role = Column(Integer, ForeignKey("roles.id"), nullable=False)
    ...

И наши отношения:

# Define relationship between a User and their Requests
requests = relationship('Request', backref='requested_by', lazy='dynamic')

# Define relationship between a Role and Requests for this Role
requests = relationship('Request', backref='requested_role', lazy='dynamic')

И, наконец, цель:

# Return any requests made by a user or a role matching the search query
data = Request.query.filter(or_(Request.requested_by.name.contains(search_query),
                                Request.requested_by.username.contains(search_query),
                                Request.requested_role.name.contains(search_query))).all()

Выполнение приведенного выше кода приводит к следующему:

AttributeError: Neither 'InstrumentedAttribute' object nor 'Comparator' object associated with Request.requested_by has an attribute 'name'

Идея здесь в том, чтобы иметь возможность искать объекты запроса по релевантным деталям пользователя или связанной с ними роли. Это возможно?

1
JTApps 26 Фев 2016 в 20:07

1 ответ

Лучший ответ

Да. Вам нужно выполнить соединение:

Request.query.join(Request.requested_by) \
             .join(Request.requested_role) \
             .filter(or_(User.name.contains(search_query),
                         User.username.contains(search_query),
                         Role.name.contains(search_query)))

Обратите внимание, что это создает запросы LIKE '%whatever%', которые невероятно неэффективны, если у вас большая таблица.

1
univerio 26 Фев 2016 в 22:49
Есть ли более эффективные способы поиска в этих таблицах с точки зрения производительности? Спасибо за ответ
 – 
JTApps
29 Фев 2016 в 17:21
Зависит от вашего конкретного случая, но если вы не хотите менять способ запроса, вы можете посмотреть pg_trgm. Полнотекстовый поиск - это еще один подход, но он может не работать. для имен пользователей.
 – 
univerio
29 Фев 2016 в 21:48
Оба этих решения ограничены PostgreSQL?
 – 
JTApps
29 Фев 2016 в 23:10
Извините, я предполагал, что вы используете PostgreSQL. Другие СУБД обычно имеют полнотекстовые возможности, например MySQL и SQL Server. Обратите внимание, что полнотекстовый поиск обычно индексирует слова, поэтому поиск произвольной подстроки обычно не работает. Вы также можете изучить специальный сервер поиска, например ElasticSearch.
 – 
univerio
29 Фев 2016 в 23:15
В настоящее время используется SQLite и будет переходить на пост-разработку Oracle. Надеюсь, я смогу найти верное решение, поскольку просматриваемые таблицы относительно велики.
 – 
JTApps
29 Фев 2016 в 23:28