首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在sqlalchemy hybird表达式中运行查询?

如何在sqlalchemy hybird表达式中运行查询?
EN

Stack Overflow用户
提问于 2018-05-27 14:33:15
回答 1查看 701关注 0票数 2

有一个与类标记有“有很多”关系的类运行。我需要能够基于标记的函数(tag_collection)过滤运行。

下面是我的代码片段。在这种情况下,我使用的是自动驾驶,但我不认为这太重要了。

代码语言:javascript
复制
Base = automap_base()

class Run(Base):
    __tablename__ = 'runs'
    macro_id = Column(ForeignKey('macros.id'))  

    @hybrid_property
    def tag_count(self):
        return(len(self.tag_collection))

    @hybrid_property
    def default_region(self):
        return(reduce(lambda  memo, t: memo or t.name == "region" and t.value == "default", self.tag_collection, False))

    @default_region.expression
    def default_region(cls):
        # how do I do the query here?

class Tag(Base):
    __tablename__ = 'tags'
    run_id = Column(ForeignKey('runs.id'))    

如果我得到一个运行实例,我可以使用default_region属性,但是当我运行一个查询并尝试使用default_region属性进行筛选时,我要么在@hybird_property修饰的default_region方法中传递Run类(作为self),要么在@default_region.expression修饰的default_region方法中结束,后者也接收Run类。

示例查询:

代码语言:javascript
复制
session.query(Run).filter(Run.default_region == True).all()

我认为我需要在@default_region.expression修饰的default_region方法中执行一个查询,但是我不知道如何获得会话的句柄。我知道Session.object_session(someobject),但我认为someobject应该是orm类的实例,而不是类本身。

我认为我的过滤方法完全错了,或者我需要在@default_region.expression修饰的default_region方法中获得会话对象的句柄。

有更好的方法来完成这个过滤吗?

如何在@default_region.expression修饰的default_region方法中获取会话?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-05-27 15:00:29

在我看来,这是一个http://docs.sqlalchemy.org/en/latest/orm/extensions/hybrid.html#correlated-subquery-relationship-hybrid。添加Run.default_region作为筛选器时,要更新要添加的查询

代码语言:javascript
复制
WHERE EXISTS (
    SELECT 1 FROM tags
    WHERE run_id = runs.id
      AND name = "region"
      AND value = "default")

使用 function将其作为表达式返回

代码语言:javascript
复制
from sqlalchemy.sql import exists, and_

@default_region.expression
def default_region(cls):
    return exists([1]).where(and_(
        Tag.run_id == cls.id,
        Tag.name == 'region',
        Tag.value == 'default'))

请注意,您希望避免在这里使用== True== False,没有必要!只需直接使用该属性:

代码语言:javascript
复制
session.query(Run).filter(Run.default_region).all()

或者使用~否定:

代码语言:javascript
复制
session.query(Run).filter(~Run.default_region).all()

通过为属性定义 method,您已经告诉SQLAlchemy在访问类上的属性时使用该方法,因此上下文始终是类。在不定义.exists (或.comparator)的情况下,Run.default_region会将default_region getter (用`@hybrid_property修饰的方法)调用为类方法,因此只有这样,该方法才能处理传入的实例或类。对于某些混合属性实现来说,这恰好取决于它们在上下文中使用属性的方式。

至于default_region实例属性的实现,我不会在那里使用reduce();使用 function

代码语言:javascript
复制
@hybrid_property
def default_region(self):
    return any(
        t.name == "region" and t.value == "default"
        for t in self.tag_collection)

当找到匹配时,any()停止对提供的生成器表达式进行迭代。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50553203

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档