【问题标题】:SQLAlchemy Query Possible?SQLAlchemy 查询可能吗?
【发布时间】:2014-06-04 04:04:51
【问题描述】:

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

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

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

【问题讨论】:

  • 使用filter_by(name="stuff")filter(Game_Table.name=="stuff")
  • 保罗,你错过了问题的重点。我想获取条目列表然后存储它。然后使用保存的条目列表,继续对其进行 sqlalchemy 类型的操作。
  • 在没有.all()的情况下存储它(这个方法会把它变成一个列表,防止你以后链接方法)
  • 没有 .all() 它只是一个查询,它实际上并没有收集项目。关键是我想查询数据库并获取游戏列表,然后多次操作该列表。所以我只想查询和构建一次列表以节省时间。
  • 我认为你应该使用一个更具描述性的标题,没有人会真正通过谷歌找到这个问题。

标签: python sql sqlalchemy


【解决方案1】:

.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)

【讨论】:

  • 这么说好像没有办法做我想做的事?
  • 好的,谢谢您的回答。抱歉,如果我在原始问题中不清楚。如果没有其他人提出解决方案,我会在一两天内接受您的回答。
  • 查看我的更新,如果内存中已有结果,在 Python 中进行过滤是否有意义?
  • 保罗,这就是我现在正在做的事情。但是我仍然想通过 SQLAlchemy 来完成它,因为它是一种更直观的方式来构建我正在制作的这些程序。
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

    您可以使用 python 或 sqlalchemy 过滤器过滤您的列表。但是你不能在all()返回的python列表上使用sqlalchemyfilter()

    您可以在 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-17
      • 2014-01-02
      • 1970-01-01
      • 2014-01-05
      • 2011-04-07
      • 1970-01-01
      • 1970-01-01
      • 2015-10-24
      相关资源
      最近更新 更多