首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >sqlalchemy: hybrid_property的布尔表达式

sqlalchemy: hybrid_property的布尔表达式
EN

Stack Overflow用户
提问于 2019-02-28 19:44:41
回答 1查看 732关注 0票数 1

我有一个sqlalchemy类,它表示一个包含列FileIDSettlementDate的表。我想创建一个混合属性来说明给定实例是否是其SettlementDate的最大FileID,以及在查询时使用的关联表达式。我已经成功地让属性工作了,但我正在努力处理表达式。以下是现有的模型:

代码语言:javascript
复制
class Hdr(model.Base):

    id = Column('ID', Integer, primary_key=True)
    file_id = Column('FileID', BIGINT, ForeignKey('FileRegister.Files.ID'))
    settlement_date = Column('SettlementDate', Date)

    @hybrid_property
    def is_latest(self):
        subquery = (
            object_session(self)
            .query(func.max(Hdr.file_id).label('file_id'))
            .group_by(Hdr.settlement_date)
            .subquery()
        )

        return (
            object_session(self)
            .query(func.count(Hdr.file_id).cast(Boolean))
            .filter(subquery.c.file_id==self.file_id)
            .scalar()
        )

我想我可以做一些类似的事情:

代码语言:javascript
复制
subquery = (
    select((func.max(Hdr.file_id).label('file_id'), ))
    .group_by(Hdr.settlement_date)
    .alias('a')
)

s = select(
    case(
        whens=[
            (Hdr.file_id.in_(subquery), 1)
        ],
        else_=0
    )
)

但这会引发错误Boolean value of this clause is not defined

任何帮助都将不胜感激!

回溯如下:

代码语言:javascript
复制
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
c:\Users\\venvs\insight\lib\site-packages\sqlalchemy-1.3.0b3-py3.7-win-amd64.egg\sqlalchemy\sql\selectable.py in __init__(self, columns, whereclause, from_obj, distinct, having, correlate, prefixes, suffixes, **kwargs)
   2889         try:
-> 2890             cols_present = bool(columns)
   2891         except TypeError:

c:\Users\\venvs\insight\lib\site-packages\sqlalchemy-1.3.0b3-py3.7-win-amd64.egg\sqlalchemy\sql\elements.py in __bool__(self)
    515     def __bool__(self):
--> 516         raise TypeError("Boolean value of this clause is not defined")
    517 

TypeError: Boolean value of this clause is not defined

During handling of the above exception, another exception occurred:

ArgumentError                             Traceback (most recent call last)
<ipython-input-20-4946a4bf7faa> in <module>
     10             (Hdr.file_id.in_(subquery), 1)
     11         ],
---> 12         else_=0
     13     )
     14 )

<string> in select(columns, whereclause, from_obj, distinct, having, correlate, prefixes, suffixes, **kwargs)

<string> in __init__(self, columns, whereclause, from_obj, distinct, having, correlate, prefixes, suffixes, **kwargs)

c:\Users\\venvs\insight\lib\site-packages\sqlalchemy-1.3.0b3-py3.7-win-amd64.egg\sqlalchemy\util\deprecations.py in warned(fn, *args, **kwargs)
    128                     )
    129 
--> 130             return fn(*args, **kwargs)
    131 
    132         doc = fn.__doc__ is not None and fn.__doc__ or ""

c:\Users\\venvs\insight\lib\site-packages\sqlalchemy-1.3.0b3-py3.7-win-amd64.egg\sqlalchemy\sql\selectable.py in __init__(self, columns, whereclause, from_obj, distinct, having, correlate, prefixes, suffixes, **kwargs)
   2891         except TypeError:
   2892             raise exc.ArgumentError(
-> 2893                 "columns argument to select() must "
   2894                 "be a Python list or other iterable"
   2895             )

ArgumentError: columns argument to select() must be a Python list or other iterable
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-03-01 04:27:44

问题是

代码语言:javascript
复制
s = select(case(...))

select()的第一个参数应该是列元素或from子句对象的序列。似乎在某个时刻,SQLAlchemy会通过执行bool(columns)来检查传递的序列是否为空。解决方案是简单地将其包装在一个序列中,就像您在创建subquery时所做的那样

代码语言:javascript
复制
s = select([case(...)])

在混合属性的“Python端”中,不计算任何settlement_date的最大file_id是否恰好与实例的最大值匹配,而是可以根据实例的settlement_date进行筛选并检查最大值:

代码语言:javascript
复制
class Hdr(model.Base):

    @hybrid_property
    def is_latest(self):
        max_file_id = (
            object_session(self)
            .query(func.max(Hdr.file_id))
            .filter(Hdr.settlement_date == self.settlement_date)
            .scalar()
        )

        return max_file_id == self.file_id

在表达式中,您不需要将布尔表达式包装在标量子查询中,而是返回布尔表达式本身:

代码语言:javascript
复制
    @is_latest.expression
    def is_latest(cls):
        hdr_alias = aliased(Hdr)
        subquery = (
            select([func.max(hdr_alias.file_id)])
            .group_by(hdr_alias.settlement_date)
        )

        return cls.file_id.in_(subquery)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54924977

复制
相关文章

相似问题

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