我正在评估从Peewee转换到Pony ORM。在Peewee中可用的一个好处是可以像这样从部分组合查询:
这个工作的原理是,Peewee模型类型上的各种操作符重载只是返回一个查询组件的树,这些子树可以通过进一步的操作符重载进行组合。同时,可以用
然而,在Pony ORM中,似乎只有(相当聪明的!)AST生成器解析器和原始SQL。由于原始SQL形式不容易让我传递必要的查询部分,如果可能的话,我更愿意使用一些高级别的查询构建功能。
如果我尝试将查询部分定义为模型上的方法,例如:
我得到了一个
是否有一种从现有部分构建查询表达式的机制,以便将其传递给SQL查询生成器?(也许通过自己构建AST并将其传递到Pony的相关部分,或者通过一种机制,我将查询传递给另一个子查询进行过滤。)
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的相关部分,或者通过一种机制,我将查询传递给另一个子查询进行过滤。)