[英]sqlalchemy: Boolean expression for hybrid_property
I have a sqlalchemy class that represents a table with columns FileID
and SettlementDate
. 我有一个sqlalchemy类,它表示具有
FileID
和SettlementDate
列的表。 I want to create a hybrid property to say whether a given instance is the maximum FileID
for its SettlementDate
, and an associated expression to use when querying. 我想创建一个混合属性,以说给定实例是否为其
SettlementDate
的最大FileID
以及查询时要使用的关联表达式。 I've successfully got the property working, but am struggling with the expression. 我已经成功地使该属性正常工作,但是在表达上却有些挣扎。 Here's the existing model:
这是现有模型:
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()
)
I'd like to think I can do something along the lines of: 我想我可以按照以下方式做点事情:
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
)
)
But this raises an error Boolean value of this clause is not defined
. 但这会引发错误
Boolean value of this clause is not defined
。
Any help would be greatly appreciated! 任何帮助将不胜感激!
Traceback follows: 追溯如下:
---------------------------------------------------------------------------
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
The problem is 问题是
s = select(case(...))
The first argument to select()
should be a sequence of column elements or from clause objects. select()
的第一个参数应该是列元素或from子句对象的序列。 It seems that SQLAlchemy at some point checks if the passed sequence is empty or not by doing bool(columns)
. 似乎SQLAlchemy可以通过执行
bool(columns)
检查所传递的序列是否为空。 The solution is to simply wrap it in a sequence, as you have done in creating the subquery
: 解决方案是将其简单地包装成一个序列,就像创建
subquery
所做的那样:
s = select([case(...)])
In the hybrid property's "Python side" instead of counting if the maximum file_id
of any settlement_date
happens to match the instance's you could filter by the instance's settlement_date
and check against the maximum: 在混合属性的“ Python端”,而不是计算是否任何
settlement_date
的最大file_id
恰好与实例相匹配,您可以按实例的settlement_date
过滤并检查最大值:
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
In the expression you don't need to wrap the boolean expression in a scalar subquery, but return the boolean expression itself: 在表达式中,您不需要将布尔表达式包装在标量子查询中,而是返回布尔表达式本身:
@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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.