当前位置: 首页 > 面试题库 >

在SQLAlchemy中,为什么我的load_only不过滤我指定的任何列?

端木昱
2023-03-14
问题内容

基本上,我已经在正常的完整查询中创建了一个数据库,这是我使用的代码以及生成的响应。

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专门选择一列时,在这种情况下为email列。我使用的代码是:

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显示AttributeState.loaded_value为符号
NO_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}>"


 类似资料:
  • 我的mavensettings.xml如下,如你所见,没有超文本传输协议repository url,所有repository url都是以https开头的。 当我执行 gradle 构建时,它说我使用不安全的协议。事实上,我从来没有在我的专家设置中使用过http协议.xml。我们可以看到所有存储库 URL 都以“https://”开头。任何人都可以给我一些建议吗? 我的gradle版本是7.4部

  • 我正在使用PDFBox通过扩展PDFTextStripper从文档中提取文本。我注意到其中一些文档包含正在提取的不可见字符。我想过滤掉这些不可见的字符。 我看到已经有一些关于这个的stackoverflow帖子,例如: PDFBox-删除不可见文本(通过剪辑/填充路径问题) 使用pdfbox从pdf中删除不可见的文本 我尝试对此处找到的类进行子类化: https://github.com/mkl-

  • 我用create-react-app开始这个项目,然后弹出。我正在分析我的webpack包,我得到了这个。 我运行这个命令来分析我的捆绑包- 我有几个问题- > 我在我的应用程序中使用了moment.js,但是当查看我的package.json时,它不在那里。它确实存在于我的纱锁里。为什么会出现这种情况?为什么我的应用程序还能工作? 我使用lodash,但我已经注意导入特定的lodash函数(例如

  • 问题内容: 当渴望加载子关系时,如何仅加载父模型的几列: 如果我仅需要模型的列,则此方法有效: 但这会引发错误: 查询仅具有基于表达式的实体-找不到名为“章节”的属性。 换句话说,我希望使用ORM语法编写此SQL: 问题答案: 错误消息指出您只是选择,而不是的实例。如果返回的只是字符串列表(用于),该去哪里。 您可以执行以下任一操作: 或者

  • 我阅读了一些文章,发现:默认情况下,预启用了以下HttpMessageConverters实例: ByteArrayHttpMessageConverter-转换字节数组 StringHttpMessageConverter-转换字符串 ResourceHttpMessageConverter-转换org.springframework.core.io.resource用于任何类型的八位组流 So

  • 我为我的朋友创建了一个项目,我想问我如何使用PyInstaller解决我的问题? 我的问题是当我打字的时候 PyInstermyprogram.py 它确实创建了文件夹,但是我在其中的任何地方都找不到。它应该在dist,但它不是。