使用 PonyORM 查询可选参数
Query with optional arguments using PonyORM
我正在为团队建设游戏库构建 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)
它们填充有不同的 types/lengths/size 值,然后分配给不同的游戏。这很好用。
我很难弄清楚如何让数据库用户查询例如其中两个,第三个没有给出。例如,我想要所有 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 语句的情况下立即在查询中使用变量?
您可以在 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)
我正在为团队建设游戏库构建 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)
它们填充有不同的 types/lengths/size 值,然后分配给不同的游戏。这很好用。
我很难弄清楚如何让数据库用户查询例如其中两个,第三个没有给出。例如,我想要所有 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 语句的情况下立即在查询中使用变量?
您可以在 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)