检查多个ORM关系的字段是不是包含值
Posted
技术标签:
【中文标题】检查多个ORM关系的字段是不是包含值【英文标题】:Checking to see if the fields of multiple ORM relationships contain a value检查多个ORM关系的字段是否包含值 【发布时间】:2016-02-26 17:07:59 【问题描述】:请求(我正在搜索的对象)由分配角色的用户组成,由所述请求表示。见下文:
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】:是的。您需要加入:
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%'
查询,如果您有一个大表,这将非常低效。
【讨论】:
在性能方面是否有更好的方法来搜索这些表?感谢您的回答 @JTApps 取决于您的具体情况,但如果您不想更改查询方式,您可以查看pg_trgm
。 Full-text search 是另一种方法,但它可能不适用于用户名。
这两种解决方案都仅限于 PostgreSQL 吗?
@JTApps 抱歉,我以为您使用的是 PostgreSQL。其他 RDBMS 通常具有全文功能,例如mysql 和 SQL Server。请注意,全文搜索通常会索引单词,因此搜索任意子字符串通常效果不佳。您可能还想查看专用的搜索后端,例如ElasticSearch.
目前使用 SQLite 并将过渡到 Oracle 后期开发。希望我能找到一个有效的解决方案,因为正在搜索的表相对较大。以上是关于检查多个ORM关系的字段是不是包含值的主要内容,如果未能解决你的问题,请参考以下文章