2016-03-02 82 views
0

我有时需要在不同的查询中重用某个SQL表达式。如果表达式在所有情况下都查询同一个表,那么模型似乎是一个放置它的好地方。但是,我并不总是需要标量属性,如果我不需要它,我不想实现它。SQLAlchemy - 将表达式附加到模型

这里是我如何做到这一点:

@hybrid_property 
def some_property(self): 
    """Allows the query-level expression to exist.""" 
    raise NotImplemented 

@some_property.expression 
def some_property(cls): 
    """Query blah blah blah.""" 
    return case(
     ... snip ... 
    ).label('some_property') 

现在,标量实现不做任何事情(提高NotImplemented)。我怎样才能避免写它?

我不能作出这样的表达一类属性,因为我需要参考在它的类,你不能指一类类级代码:

class A(object): 
    c = A # NameError 

我理论上可以使它成为一个类 - 但是没有很好的实施。

我能想到的唯一选择是在创建类并将其分配给类之后创建表达式。这是邪恶的。

回答

1

你就不能做到这一点:

@declared_attr 
def some_property(cls): 
    """Query blah blah blah.""" 
    return case(
     ... snip ... 
    ).label('some_property') 
1

你可以尝试将其实现为column property。列属性就像只有表达式部分的混合属性(这是你想要的,对吧?)。有一些限制,但对我来说这通常是有效的。使用deferred=true可以避免在不需要时进行评估。

some_property = column_property(
    select(**some column**).where(**some conditon**), 
    deferred=true 
)