首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用PonyORM使用可选参数进行查询

使用PonyORM使用可选参数进行查询
EN

Stack Overflow用户
提问于 2019-05-26 19:00:33
回答 1查看 119关注 0票数 2

我正在为一个团队建设游戏的库构建一个API。游戏定义了类型、大小和长度等属性,我将这些属性存储为多对多关系。该模型如下所示:

代码语言:javascript
复制
class Game(db.Entity):
    game_type = Set('Type')
    game_length = Set('Length')
    group_size = Set('GroupSize')
    ...

class Type(db.Entity):  # similar for Length, GroupSize
    game = Set(Game)
    short = Required(str)
    full = Required(str)

它们由不同的类型/长度/大小值填充,然后分配给不同的游戏。这可以很好地工作。

我花了很长时间才弄明白如何让数据库用户查询其中的两个,而第三个没有给出。例如,我想要除length=None之外的所有使用type=race AND size=medium的游戏。

我之前已经用子查询和空字符串在SQL中构建了它。这是我第一次尝试使用PonyORM:

代码语言:javascript
复制
def get_all_games(**kwargs):
    game_type = kwargs.get('game_type', None)
    group_size = kwargs.get('group_size', None)
    game_length = kwargs.get('game_length', None)

    query = select((g, gt, gs, gl) for g in Game
                                     for gt in g.game_type
                                       for gs in g.group_size
                                         for gl in g.game_length)

    if game_type:
        query = query.filter(lambda g, gt, gs, gl: gt.short == game_type)
    if group_size:
        query = query.filter(lambda g, gt, gs, gl: gs.short == group_size)
    if game_length:
        query = query.filter(lambda g, gt, gs, gl: gl.short == game_length)

    query = select(g for (g, gt, gs, gl) in query)

    result = []

    for g in query:
        this_game = get_game(g)
        result.append(this_game)

    return result

这对我来说似乎太复杂了。有没有办法在不打包和解包的情况下做到这一点?也许可以在查询中立即使用变量,而不使用if语句?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-05-27 15:43:07

您可以在filter中使用existsin。您还可以使用attribute lifting来简化复杂的连接:

代码语言:javascript
复制
query = Game.select()

if game_length:
    # example with exists
    query = query.filter(lambda g: exists(
        gl for gl in g.game_length
        if gl.min <= game_length and gl.max >= game_length))

if group_size:
    # example with in
    query = query.filter(lambda g: group_size in (
        gs.value for gs in g.group_sizes))

if game_type:
    # example with attribute lifting
    query = query.filter(lambda g: game_type in g.game_types.short)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56312903

复制
相关文章

相似问题

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