Я создаю 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?