Я рассматриваю возможность перехода с peewee на Pony ORM. Одна приятная вещь, которая была доступна в peewee, — это возможность составить запрос из таких частей:
def Entry(BaseModel):
# peewee fields go here
def where_entry_category(category, recurse=False):
""" Generate a where clause for a particular category """
if category or not recurse:
cat_where = (Entry.category == str(category))
if recurse:
# We're recursing and aren't in /, so add the prefix clause
cat_where = cat_where | (
Entry.category.startswith(str(category) + '/'))
else:
cat_where = True
return cat_where
query = Entry.select().where(where_entry_category("test"))
Это работает следующим образом: различные перегрузки операторов для типа модели peewee просто возвращают дерево компонентов запроса, и эти поддеревья могут быть составлены из дополнительных перегрузок операторов. Также легко иметь несколько компонентов запроса, которые объединяются в цепочку с операторами &
или |
, например. model.Entry.select().where(some_test() & some_other_test())
. Это очень полезно, так как многие мои фильтрующие запросы составлены по модульному принципу, и большинство базовых частей запроса часто используются повторно, и многие из них нетривиальны (например, в приведенном выше примере).
Однако в Pony ORM, похоже, есть только (довольно умный!) Анализатор генератора AST и чистый SQL. Поскольку необработанная форма SQL не позволяет мне напрямую передать необходимые части запроса, я бы предпочел использовать некоторые функции построения запросов более высокого уровня, если это вообще возможно.
Если я попытаюсь определить части запроса как методы модели, например:
class Entry(db.Entity):
...
def in_category(self, category, recurse=False):
# return a test on the parameters
orm.select(entry for entry in model.Entry if entry.in_category('foo', True))
Я получаю NotImplementedError
, что неудивительно.
Существует ли механизм построения выражения запроса из существующих частей для передачи в построитель запросов SQL? (Возможно, самостоятельно создав AST и передав его в соответствующую часть Pony, или используя механизм, в котором я передаю запрос для фильтрации другим подзапросом.)