我有一个球队名单。对于列表中的每个团队名称,我想从数据库中获取行,但我只想对数据库进行一次调用,并且sql炼金术对象列表需要保留原始列表的顺序。我将在原始列表中包含重复的名称。
我需要这样的东西,但是工作(我正在做的查询显然不起作用,因为它返回由id排序的所有内容)
teams_names = ['Liverpool', 'Arsenal', 'Utd', 'Liverpool']
Session.query(Team).filter(Team.name.in_(teams_names)).all()
teams_sa_obj = [#sa_liverpool, #sa_arsenal, #sa_utd, #sa_liverpool]
答案 0 :(得分:3)
我通常在Python中进行重新排序。我的想法是你为Team
个对象构建一个名称映射,然后在迭代原始列表时查找它们:
q = Session.query(Team).filter(Team.name.in_(teams_names))
team_map = {t.name: t for t in q}
teams = [team_map[n] for n in teams_names]
有SQL端解决方案,但这些与SQLAlchemy有点尴尬。
答案 1 :(得分:0)
PostgreSQL中一种尴尬的SQL解决方案是use WITH ORDINALITY and a JOIN:
teams_names = ['Liverpool', 'Arsenal', 'Utd', 'Liverpool']
teams_names = text("""SELECT *
FROM unnest(:teams_names) WITH ORDINALITY dummy(name, ord)""").\
bindparams(teams_names=teams_names).\
columns(name=String, ord=Integer).\
alias()
Session.query(Team).\
join(teams_names, teams_names.c.name == Team.name).\
order_by(teams_names.c.ord).\
all()
不幸的是,SQLAlchemy尚不支持WITH ORDINALITY,因此为了避免必须生成custom compiler extension,需要笨拙的text()
构造,但是另一方面,自定义构造会提高的可读性。 Python代码。