Sqlalchemy选择条件

时间:2011-10-21 11:09:38

标签: python sqlalchemy

我在表上有一个映射器,我想定义一个column_property,它应该选择True或False,无论该实体是否具有某些属性:

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 个答案:

答案 0 :(得分:3)

您的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将如何解释这一点,但它肯定不会像你想象的那样有效。

您必须使用sqlalchemy.sql.expression.case()而不是if ... else ...重写此表达式,使其与普通SQL相对应:

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))

但是,在您的情况下,可能会有一个更简单的解决方案。 PersonRole似乎有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)