noload for scalar attributes behaves like lazyload

Issue #3510 resolved
Adrian created an issue

I would expect the last print in this script to show None, but as of 1.0.x it shows a C object (which is lazy-loaded).

from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()


class A(Base):
    __tablename__ = 'test_a'

    id = Column(Integer, primary_key=True)


class B(Base):
    __tablename__ = 'test_b'

    id = Column(Integer, primary_key=True)
    a_id = Column(Integer, ForeignKey('test_a.id'))
    c_id = Column(Integer, ForeignKey('test_c.id'))
    a = relationship('A', backref=backref('b'))
    c = relationship('C', backref=backref('b'))


class C(Base):
    __tablename__ = 'test_c'

    id = Column(Integer, primary_key=True)


e = create_engine('sqlite:///:memory:', echo=True)
Base.metadata.create_all(e)

s = Session(e)
s.add(B(a=A(), c=C()))
s.commit()

a = s.query(A).options(joinedload('b').noload('c')).all()
print a[0]
print a[0].b[0]
print a[0].b[0].c

Script + full output: https://gist.github.com/ThiefMaster/d6c16d26c77507612b0d

Comments (8)

  1. Adrian reporter

    kind of unrelated, but a "strict" noload strategy that fails with an exception instead of returning None would be nice - i guess when explicitly deciding not to load a relationship you expect your code not to access it, so if it does something is likely wrong, and with an exception you'd notice it easily

  2. Log in to comment