简体   繁体   English

SQLAlchemy:根据表字段查询自定义属性

[英]SQLAlchemy: query custom property based on table field

I'm using SQLAlchemy declarative base to define my model. 我正在使用SQLAlchemy声明基础来定义我的模型。 I defined a property name that is computed from one the columns ( title ): 我定义了一个属性name ,该name是从列( title )中计算出来的:

class Entry(Base):
    __tablename__ = "blog_entry"
    id = Column(Integer, primary_key=True)
    title = Column(Unicode(255))
    ...

    @property
    def name(self):
        return re.sub(r'[^a-zA-Z0-9 ]','',self.title).replace(' ','-').lower()

When trying to perform a query using name , SQLAlchemy throws an error: 尝试使用name执行查询时,SQLAlchemy会抛出错误:

Session.query(Entry).filter(Entry.name == my_name).first()
>>> ArgumentError: filter() argument must be of type sqlalchemy.sql.ClauseElement or string

After investigating for a while, I found that maybe comparable_using() could help, but I couldn't find any example that shows a comparator that references another column of the table. 经过一段时间的调查,我发现也许comparable_using()可能有所帮助,但我找不到任何显示比较器引用表的另一列的示例。

Is this even possible or is there a better approach? 这是可能的还是有更好的方法?

从SqlAlchemy 0.7您可以使用hybrid_property实现这一点,请参阅此处的文档: http ://www.sqlalchemy.org/docs/orm/extensions/hybrid.html

Can you imagine what SQL should be issued for your query? 你能想象应该为你的查询发出什么SQL吗? The database knows nothing about name , it has neither a way to calculate it, nor to use any index to speed up the search. 数据库对name一无所知,它既没有计算方法,也没有使用任何索引来加速搜索。

My best bet is a full scan, fetching title for every record, calculating name then filtering by it. 我最好的选择是全扫描,为每条记录获取title ,计算name然后按其过滤。 You can rawly do it by [x for x in Session.query(Entry).all() if x.name==my_name][0] . [x for x in Session.query(Entry).all() if x.name==my_name][0]你可以通过[x for x in Session.query(Entry).all() if x.name==my_name][0] Session [x for x in Session.query(Entry).all() if x.name==my_name][0] With a bit more of sophistication, you'll only fetch id and title in the filtering pass, and then fetch the full record(s) by id . 稍微复杂一点,你只需要在过滤过程中获取idtitle ,然后按id获取完整的记录。

Note that a full scan is usually not nice from performance POV, unless your table is quite small. 请注意,除非您的表非常小,否则从性能POV开始,完整扫描通常并不好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM