Я оцениваю переход с 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, или имея механизм, с помощью которого я передаю запрос для фильтрации другим подзапросом.)