2011-10-21 52 views
1

我有一個表上的映射器,我想定義一個column_property應該選擇真或假的實體是否有一些propertie與否: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],它讓我根據條件爲列設置一個值。

+0

它有BW因爲它是一個列屬性。你與sqlalchemy合作過嗎? –

回答

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會如何解釋這一點,但它肯定不會按照你的意圖工作。

你將不得不重寫這個表達,使其將對應於普通的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)) 

在你的情況,但是,有可能是一個更簡單的解決方案。 PersonRole似乎有一個N:1關係(一個人只有一個角色)。我假設有一個orm.relationshipPerson.role得到一個人的角色。

你爲什麼不只需添加一個普通的Python屬性:

class Person: 
    # ... 

    @property 
    def administrator(self): 
     return self.role and (self.role.is_admin or self.role.id == 1)