2016-03-02 3 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 

я теоретически могу сделать это class- но для этого нет хорошей реализации.

Единственная альтернатива, о которой я могу думать, заключается в создании выражения позже, после создания класса и назначения его классу. Который злой.

ответ

1

Разве вы не можете просто сделать это:

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

Вы можете попробовать реализовать его как column property. Свойство column похоже на гибридное свойство с только частью выражения (что вам нужно, правильно?). Есть некоторые ограничения, но для меня это обычно срабатывает. Используя deferred=true, вы можете избежать его оценки, когда это не требуется.

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