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
将会打印:
<User(1, 'bob', None, None)>
<User(2, 'joe', None, None)>
...
这样做可能吗?如果可以的话,怎么做?
3 个回答
关于 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
对我来说,一个简单的解决办法是:
users = session.query(User.userid, User.name)
for user in users:
print user
这段代码会输出:
<User(1, 'bob')>
<User(2, 'joe')>
...
你可以查询单独的列,这样会返回一些命名元组,这些元组实际上和你映射的对象很像,特别是当你把它们传给模板或者其他地方使用的时候:
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"]))
defer() 其实应该支持多个参数,我为此添加了一个票据 #2250(编辑:正如评论中提到的,这个功能在0.9版本中作为 load_only() 提供)