python - 在 SQLAlchemy 中,为什么我的 load_only 不过滤我指定的任何列?
问题描述
基本上我已经创建了一个数据库,在正常的完整查询中,这是我使用的代码和生成的响应。
db.session.query(User).all()
生成的查询如下:
<User(email='howard@howard.com', fullname='Howard', company='howard', address='None', password='howard')>, <User(email='emailhoward', fullname='None', company='None', address='None', password='passwordhoward')>
这是合乎逻辑的,因为我正在从表中提取所有内容。但是,当我尝试使用 load_only 专门选择一列时,在本例中为电子邮件列。我使用的代码是:
db.session.query(User).options(load_only(User.address)).all()
db.session.query(User).options(load_only('email')).all()
这两个命令都给了我相同的结果:
<User(email='howard@howard.com', fullname='Howard', company='howard', address='None', password='howard')>,<User(email='emailhoward', fullname='None', company='None', address='None', password='passwordhoward')>
这非常奇怪,因为我应该在查询中只得到一列。但是,当我使用这个时:
db.session.query(User.email).select_from(User).filter_by(email=email).first()[0]
它神奇地只为我返回一列。我需要使用 load_only,因为我有动态表,我想重用相同的函数,而不是维护许多函数集。谁能告诉 load_only 命令有什么问题,或者我做错了什么?
谢谢你。
解决方案
没有问题,只是有点误会;
<User(email='howard@howard.com', fullname='Howard', company='howard', address='None', password='howard')>
是模型对象的字符串表示形式,它是在访问延迟列时拉入延迟列的方法。User
User.__repr__()
使用load_only()
您定义一组列以最初为实体加载,同时延迟所有其他列。但是推迟一列并不意味着它在某种程度上无法使用或包含一些“无价值”标记(实际上它确实如此,在引擎盖下)。当第一次引用每个延迟属性时,SQLAlchemy 将发出一个 SELECT 以获取其值。这从日志中应该很明显:
In [7]: u = session.query(User).options(load_only(User.email)).first()
2018-05-14 16:04:49,218 INFO sqlalchemy.engine.base.Engine SELECT user.id AS user_id, user.email AS user_email
FROM user
LIMIT ? OFFSET ?
2018-05-14 16:04:49,218 INFO sqlalchemy.engine.base.Engine (1, 0)
In [8]: u.fullname
2018-05-14 16:04:53,773 INFO sqlalchemy.engine.base.Engine SELECT user.fullname AS user_fullname
FROM user
WHERE user.id = ?
2018-05-14 16:04:53,773 INFO sqlalchemy.engine.base.Engine (2,)
Out[8]: 'Bar'
您可以使用检查 API 检查列是否已被延迟。InstanceState.unloaded
保存没有加载值的键集。使用它,您可以将您的修改User.__repr__
为:
class User(Base):
...
def __repr__(self):
state = inspect(self)
def ga(attr):
return (repr(getattr(self, attr))
if attr not in state.unloaded
else "<deferred>")
attrs = " ".join([f"{attr.key}={ga(attr.key)}"
for attr in state.attrs])
return f"<User {attrs}>"
或者,您可以遍历display,如果尚未加载值,则计算为符号InstanceState.attrs
NO_VALUE :AttributeState.loaded_value
class User(Base):
...
def __repr__(self):
state = inspect(self)
attrs = " ".join([f"{attr.key}={attr.loaded_value!r}"
for attr in state.attrs])
return f"<User {attrs}>"
推荐阅读
- sql - Oracle 中的 IF ELSE 条件需要帮助
- neo4j - Neo4j 通过原生 api 创建索引的问题
- vb.net - 如何进行循环以查找匹配的字符串
- azure - 有没有办法在任务运行时(在完成之前)从 Azue Batch 任务中动态流式传输数据
- c# - 使用模型等待多个调用
- javascript - 使用 Javascript 和 Acrobat DC 在 PDF 中提取超过 49 页时出错
- python - 模块之间的相对导入
- javascript - 在 ES6 JavaScript 模块中操作 DOM
- firebase - Firebase 如何计算字段的存储空间?Fireabase 存储报告过度使用
- svg - 注释连接器阻止工具提示