【问题标题】:SQLAlchemy: Disable lazy loading and load object only on join()SQLAlchemy:禁用延迟加载并仅在 join() 上加载对象
【发布时间】:2018-12-31 20:35:36
【问题描述】:

我正在努力禁用 SQLAlchemy 上的延迟加载,因此默认情况下它不会在从数据库中获取记录时加载所有对象。例如,当您专门在查询中加入用户对象或访问它时,我试图仅从事件对象加载用户对象,例如 event.user。这是否可以通过参数以某种方式实现,或者禁用延迟加载是一种不好的做法?

我已经尝试过 noload("*") 但它在最后禁用了任何连接。 例如,我有以下模型以及我正在做的测试。

# Event model
class Event(Base):
    __tablename__ = 'events'

    id = Column(Integer, primary_key=True, autoincrement=True)
    name = Column(String(50), nullable=False)
    amount = Column(Integer)

    _user_id = Column("user_id", Integer, ForeignKey("users.id"), nullable=False)
    user = relationship(User)

# Query - This fetches also the whole user object <-- I don't want such behavior
some_session.query(Event).all()

# Query - I would like to load the user object when I will use the join() if possible
some_session.query(Event).join(Event.user).all()

【问题讨论】:

  • @IljaEverilä 是的,这是真的。我可以接受它,因为默认值是lazy="select",但是当我执行查询以获取所有事件时,我加载了整个用户对象而没有执行任何 event.user。我也会修改标题以免混淆
  • @IljaEverilä 我发布了一张图片,它在执行查询时向我显示了结果集中的用户对象。没有加载吗?
  • @IljaEverilä 我对特定对象没有任何 __repr__() 或检查。我有一个执行上述查询的函数
  • @IljaEverilä 好点。谢谢你的信息,因为我是 sqlalchemy 的新手,你帮了我很多。我会看看你给我的那个帖子。因此,为了加载用户对象,我必须使用 .join(Event.user) 这将加载对象?

标签: python sqlalchemy


【解决方案1】:

默认relationship loading strategy 是“延迟加载”,按你想要的方式工作;仅当触摸Event 对象的user 属性时,才会加载相关的User。在您的情况下,当它检查对象以将属性显示为方便的树时,它会被您的 IDE 触及,这会触发提取。同样的happens easily with custom __repr__() implementations,如果不小心的话。

如果您希望使用联接预加载相关用户,请使用joined loading

some_session.query(Event).options(joinedload(Event.user)).all()

或者如果您希望在同一查询中基于User 进行过滤,explicit join(s) and contains_eager()

some_session.query(Event).join(Event.user).options(contains_eager(Event.user)).all()

【讨论】:

  • 按照与链接中相同的 __repr__() 操作,我得到以下信息: 表示用户未加载,当我使用 contains_eager 时,它显示要加载的对象。非常感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-02-06
  • 1970-01-01
  • 2011-09-07
  • 2011-07-25
  • 2011-10-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多