Sqlalchemy 选择条件
我在一个表上有一个映射器,我想定义一个列属性,这个属性应该根据实体是否具有某个特性来选择是“真”还是“假”。
mapper( Person, persons_table, properties = {
'administrator': column_property(
select(
[True if roles_table.c.is_admin or roles_table.c.id == 1 else False],
roles_table.c.id == persons_table.c.role_id
).label( 'administrator' )
)
} )
我能做到这一点吗?我更感兴趣的是这一部分:[True if roles_table.c.is_admin or roles_table.c.id == 1 else False]
,这段代码让我可以根据条件给这个列设置一个值。
1 个回答
4
你的SELECT表达式实际上是一个Python表达式:
select([True if roles_table.c.is_admin or roles_table.c.id == 1 else False],
roles_table.c.id == persons_table.c.role_id)
sqlalchemy.select()
会把它看作:
select([True], some_expression_object)
因为列对象roles_table.c.is_admin
在布尔上下文中会被评估为True
。我不太清楚SQLAlchemy会怎么理解这个,但肯定不会按照你想的那样工作。
你需要重写这个表达式,使它符合普通SQL的格式,使用sqlalchemy.sql.expression.case()
来代替if ... else ...
:
column_property(
select([case([(roles_table.c.is_admin, 1),
(roles_table.c.id == 1, 1)], else_=0)],
roles_table.c.id == persons_table.c.role_id))
不过在你的情况下,可能有一个更简单的解决方案。Person
和Role
之间似乎有一个N:1
的关系(一个人只有一个角色)。我猜这里有一个orm.relationship
Person.role
来获取一个人的角色。
为什么不直接添加一个普通的Python属性呢:
class Person:
# ...
@property
def administrator(self):
return self.role and (self.role.is_admin or self.role.id == 1)