【问题标题】:Query with optional arguments using PonyORM使用 PonyORM 使用可选参数进行查询
【发布时间】:2019-05-26 11:00:32
【问题描述】:

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

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)

它们填充了不同的类型/长度/大小值,然后分配给不同的游戏。这很好用。

我很难弄清楚如何让数据库的用户查询例如其中两个,第三个没有给出。例如,我想要所有带有type=race AND size=medium 但length=None 的游戏。

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

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 语句的情况下立即在查询中使用变量?

【问题讨论】:

    标签: python mysql ponyorm


    【解决方案1】:

    您可以在filter 中使用exists 或in。您也可以使用attribute lifting 来简化复杂的连接:

    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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-11-14
      • 1970-01-01
      • 2021-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-17
      相关资源
      最近更新 更多