首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Pony ORM中增量构建查询

在Pony ORM中增量构建查询
EN

Stack Overflow用户
提问于 2018-09-17 09:14:49
回答 1查看 882关注 0票数 3

我正在评估从小淘气转到小马ORM。在peewee中可用的一件好事是能够从如下部分组成一个查询:

代码语言:javascript
复制
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中,似乎只有(相当聪明的!) AST generator parser和原始SQL。由于原始SQL表单不能让我直接传递必要的查询部件,所以如果可能的话,我更愿意使用一些更高级的查询构建功能。

如果我尝试将查询部分定义为模型上的方法,例如:

代码语言:javascript
复制
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的相关部分,或者有一种机制将查询传递给另一个子查询进行过滤。)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-09-18 16:22:49

在PonyORM中,有两种方法可以一步一步地合成查询。第一个是查询的filter方法:

代码语言:javascript
复制
def where_entry_category(query, category, recourse)
    if category:
        category = str(category)
        if recurse:
            query = query.filter(lambda x: x.category == category or
                                 x.category.startswith(category + '/')
        else:
            query = query.filter(lambda x: x.category == category)
    return query

query = Entry.select()
query = where_entry_category(query, "test")

从0.7.6版本开始,还可以使用以前的查询作为新查询的源:

代码语言:javascript
复制
def where_entry_category(query, category, recourse)
    if category:
        category = str(category)
        if recurse:
            query = select(x for x in query
                           if x.category == category or
                              x.category.startswith(category + '/'))
        else:
            query = select(x for x in query if x.category == category)
    return query

您可能遇到的唯一问题是,如果您希望逐步构建带有可变数量的子表达式的or子句,此时Pony还没有相应的API。我们可能会在将来的发行版中增加一种可能性,将子表达式逐步添加到or子句。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52364368

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档