2

此代码不起作用。有没有办法在 SQLAlchemy 中发生这样的事情?在下面有一个名为“Game_Table”的表,它有一个名为“name”的列。

list_of_games = session.query(Game_Table).all()
list_of_games.filter(name=="stuff").all()

编辑:此代码的目的是我需要执行相同的查询,然后多次操作结果。因此,为了优化代码,我想在开始时进行查询并获得一次结果,然后每次对相同的结果进行不同的操作。

4

3 回答 3

0

之前的任何东西.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)
于 2013-07-27T02:36:23.003 回答
0

session.query(Game_Table).all()返回一个列表。因此,您无法使用炼金术的过滤方法进一步过滤它。

filtered_list_of_games = [g for g in list_of_games if g.name=="stuff"]

于 2013-07-31T15:56:57.707 回答
0

您可以使用 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
于 2014-06-03T20:04:51.513 回答