SQLAlchemy:选择查询中对象的哪些列

kes*_*kes 19 python orm sqlalchemy

是否可以控制在SQLAlchemy的查询方法中查询哪些列,同时仍然返回您要查询的对象的实例(尽管已部分填充)?

或者SQLAlchemy是否有必要执行SELECT *映射到对象?

(我知道查询单个列是可用的,但它不会将结果映射到对象,而只映射到命名元组的组件).

例如,如果User对象具有userid,name,password和bio属性,但您希望查询仅填充它返回的对象的userid和name:

# hypothetical syntax, of course:
for u in session.query(User.columns[userid, name]).all():
    print u
Run Code Online (Sandbox Code Playgroud)

会打印:

<User(1, 'bob', None, None)> 
<User(2, 'joe', None, None)>
...
Run Code Online (Sandbox Code Playgroud)

这可能吗; 如果是这样,怎么样?

zzz*_*eek 18

您可以查询单个列,这些列返回的命名元组实际上与您映射的对象非常相似,如果您只是传递给模板或其他内容:

http://www.sqlalchemy.org/docs/orm/tutorial.html#querying

或者您可以在映射类上将各种列建立为"延迟",无论是在配置上还是使用选项:

http://docs.sqlalchemy.org/en/latest/orm/loading_columns.html#deferred-column-loading

在trac中有一个叫做"defer_everything_but()"的旧票,如果有人觉得提供测试,而且没有理由不能添加功能,这里有一个快速版本:

from sqlalchemy.orm import class_mapper, defer
def defer_everything_but(entity, cols):
    m = class_mapper(entity)
    return [defer(k) for k in 
            set(p.key for p 
                in m.iterate_properties 
                if hasattr(p, 'columns')).difference(cols)]

s = Session()
print s.query(A).options(*defer_everything_but(A, ["q", "p"]))
Run Code Online (Sandbox Code Playgroud)

defer()应该真的接受倍数,为此添加票#2250(编辑:如注释中所述,这在0.9中为load_only())

  • 在sa> = 0.9.0中,参见[`load_only()`](http://docs.sqlalchemy.org/en/latest/orm/mapper_config.html#sqlalchemy.orm.load_only) (9认同)

Eli*_*Eli 14

一个对我有用的简单解决方案是:

users = session.query(User.userid, User.name)
for user in users:
    print user
Run Code Online (Sandbox Code Playgroud)

会打印:

<User(1, 'bob')> 
<User(2, 'joe')>
...
Run Code Online (Sandbox Code Playgroud)

  • 在您的代码中,“user”不是“User”实例(问题是什么)。这是一个*命名元组*。实际上,它只会打印 `(1, 'bob')\n(2, 'joe')`。 (2认同)

Dev*_*evi 6

最新文档在load_only这里

http://docs.sqlalchemy.org/en/latest/orm/loading_columns.html#load-only-cols

如果您正在寻找一种在模型定义级别控制它的方法,请使用 deferred

http://docs.sqlalchemy.org/en/latest/orm/loading_columns.html#deferred