我正在评估从 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 模型类型上的各种运算符重载仅返回查询组件树,并且这些子树可以由进一步的运算符重载组成。拥有多个与&
or|
运算符链接在一起的查询组件也是一件简单的事情,例如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 的相关部分,或者有一种机制让我传递一个查询以被另一个子查询过滤。)