【问题标题】:SQLAlchemy load_only option doesn't work, but returns all columns, not just specified columnsSQLAlchemy load_only 选项不起作用,但返回所有列,而不仅仅是指定的列
【发布时间】:2019-06-05 18:25:03
【问题描述】:

我正在使用 SQLAlchemy 和 load_only 选项。 在我阅读load_only 文档后,我希望如果我使用load_only,我可以获得一些指定的列。但结果并非如此。有所有的列,而不是一些列。我不知道为什么。你能给我一些建议吗?

ps。我需要行实体,所以我不使用这样的查询:

session.query(table.columnA, table.columnB)

enter image description here

我正在使用 SQLAlchemy 1.3.4

class Language(Base):
    __tablename__ = 'language'
    IDX = Column(INTEGER(11), primary_key=True)
    DH_INDEX = Column(ForeignKey('dryhop.DH_INDEX', ondelete='CASCADE', onupdate='CASCADE'), index=True)
    EP_INDEX = Column(ForeignKey('expendables.EP_INDEX', ondelete='CASCADE', onupdate='CASCADE'), index=True)
    LANG_CLASS = Column(String(20), nullable=False)
    LANG_NATION = Column(String(15), nullable=False)
    LANG_COMMENT = Column(Text)
    UPDATE_TIME = Column(DateTime, server_default=text("CURRENT_TIMESTAMP"))

query= session.query(db_model.Language).options(load_only("LANG_COMMENT", "LANG_NATION"))
dir(query.first()) # 'DH_INDEX', 'EP_INDEX', 'IDX','LANG_CLASS', 'LANG_COMMENT', 'LANG_NATION', 'UPDATE_TIME'... ETC

dir(query.first()) 时,我预计只有两列

'LANG_COMMENT', 'LANG_NATION')

但结果是

'DH_INDEX', 'EP_INDEX', 'IDX','LANG_CLASS', 'LANG_COMMENT', 'LANG_NATION', 'UPDATE_TIME'

【问题讨论】:

  • SQLA 模型不实现__dir__,因此名称以通常的方式收集。结果没有任何异常。
  • @Ilja Everilä 谢谢回答!所以你的意思是 load_only 查询返回所有未指定列的列,对吗?但我知道 load_only 只返回一些列。在那个查询中,我可以得到值,query.DH_INDEX .. 这是对的吗?我希望只有两列的值
  • @Ilja Everilä 我检查了选择查询是否不同(使用 sqlalchmy echo =True)。我还检查了你的答案(stackoverflow.com/questions/50317889/…)。如果是这样,普通查询和 load_only 查询有什么区别?,我阅读了文档,但我无法使用 load_only 选项获得任何好处。非常感谢 Ilja Everilä。上次你帮了我。我很感激。

标签: python sqlalchemy


【解决方案1】:

给定一个对象,内置的dir 尝试返回该对象的有效属性列表。如果有问题的对象没有通过实现__dir__() 覆盖默认功能,则会为“普通”对象生成列表:

否则,该列表包含对象的属性名称、其类的属性名称以及其类的基类的属性的递归名称。

换句话说,您获得的列表既是从实例加载的属性(以及其他属性)的列表,也是来自类Language、其父类等的属性。

如果您想验证是否只加载了您想要的属性,您可以使用vars() 查看实例的__dict__ 属性:

In [11]: vars(query.first())
Out[11]: 
{'IDX': 1,
 'LANG_COMMENT': 'Comment',
 'LANG_NATION': 'bar',
 '_sa_instance_state': <sqlalchemy.orm.state.InstanceState at 0x7fa6414916d8>}

或者更好的是,使用 SQLAlchemy 的runtime inspection

In [37]: from sqlalchemy import inspect

In [38]: obj = query.first()

In [39]: inspect(obj).unloaded
Out[39]: {'DH_INDEX', 'EP_INDEX', 'LANG_CLASS', 'UPDATE_TIME'}

最后,请注意,无论您在load_only() 中输入什么内容,主键始终会被加载,因为it would not make sense not to,即使您是really wanted

【讨论】:

  • 非常感谢 Ilja Everilä。每一个问题,我都欠你的。谢谢!!!
猜你喜欢
  • 2023-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-02
  • 2020-02-26
  • 1970-01-01
相关资源
最近更新 更多