此代码不起作用。有没有办法在 SQLAlchemy 中发生这样的事情?在下面有一个名为“Game_Table”的表,它有一个名为“name”的列。
list_of_games = session.query(Game_Table).all()
list_of_games.filter(name=="stuff").all()
编辑:此代码的目的是我需要执行相同的查询,然后多次操作结果。因此,为了优化代码,我想在开始时进行查询并获得一次结果,然后每次对相同的结果进行不同的操作。
此代码不起作用。有没有办法在 SQLAlchemy 中发生这样的事情?在下面有一个名为“Game_Table”的表,它有一个名为“name”的列。
list_of_games = session.query(Game_Table).all()
list_of_games.filter(name=="stuff").all()
编辑:此代码的目的是我需要执行相同的查询,然后多次操作结果。因此,为了优化代码,我想在开始时进行查询并获得一次结果,然后每次对相同的结果进行不同的操作。
之前的任何东西.all
都是可重用的,但.all
会触发评估并将结果固定下来。.all
如果您打算重用查询,我的建议是永远不要存储,仅在您需要数据时使用它(这是惰性评估的重点,仅在您真正需要时获取数据)。
代替:
list_of_games = session.query(Game_Table).all()
list_of_games.filter(name=="stuff").all()
利用:
list_of_games = session.query(Game_Table)
list_of_games.all()
list_of_games.filter(name=="stuff").all()
[更新]
所以听起来没有办法做我想做的事?– 苹果恋人
AFAIK 你只能方法链查询,而不是结果。这是有道理的:如果结果已经在内存中,为什么还要往返数据库?用纯 Python 过滤/排序它会更便宜。
# old school lisper style.
sorted(list_of_games, key=lambda x: x.name)
filter(lambda x: x.name=='stuff', list_of_games)
# new style
[x for x in list_of_games if x.name=='stuff']
如果您只是对结果进行迭代,请将其设为生成器表达式 - 即使对于较大的结果,也应该比再次访问数据库更便宜。
for game in (x for x in list_of_games if x.name=='stuff'):
print_score(game)
session.query(Game_Table).all()
返回一个列表。因此,您无法使用炼金术的过滤方法进一步过滤它。
filtered_list_of_games = [g for g in list_of_games if g.name=="stuff"]
您可以使用 python 或 sqlalchemy 过滤器过滤您的列表。但是你不能filter()
在返回的 python 列表上使用 sqlalchemy all()
。
您可以仅在 python (1) 中过滤您的列表,也可以使用 sqlalchemy 过滤器 (2) 或它们的混合 (3)。
(1)在python中操作(过滤)数据:
games = session.query(Game_Table).all() #returns a list
star_games = [g for g in games if g.name.upper().startswith('star')]
old_games = [g for g in games if g.year < 1999]
(2)对你的数据库进行多次查询(顺便被查询是它的目的):
games = session.query(Game_Table) #returns a sqlalchemy query instance
star_games = games.filter(Game_Table.name.like('star%').all()
old_games = games.filter(Game_Table.date < 1999).all()
在这两种情况下,star_games 和 old_games 都包含相同的列表,第一个使用 python 过滤,后者由您的数据库引擎过滤。
(3)你也可以先用sqlalchemy过滤你的list,再用python过滤结果:
games = session.query(Game_Table).filter(Game_Table.date < 1999) #returns a python list
old_star_games = [g for g in games if g.name.upper().startswith('star')]
old_noname = [g for g in games if not g.name]
--
另外,请注意 sqlalchemy 是为过滤器重用而设计的,而不是限制数据库上的查询数量(这意味着要被查询)。使用查询重用执行与上述相同的示例:
games = session.query(Game_Table) #returns a sqlalchemy query instance
old_games = games.filter(Game_Table.date < 1999) #also returns a sqla query instance,
#which you can reuse (see below)
old_star_games = old_games.filter(Game_Table.name.like('star%').all()
old_noname = old_games.filter(Game_Table.name == None).all()
star_games = games.filter(Game_Table.name.like('star%').all() #this one does not filter on date