descriptive error message when attempting to repurpose an instrumented attribute

Issue #3858 new
Mehdi Gmira created an issue

Hey,

Here is the test case:

from sqlalchemy import Column, DateTime, String, Integer, ForeignKey, func, Table, create_engine
from sqlalchemy.orm import relationship, backref, sessionmaker, joinedload, contains_eager
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()
engine = create_engine('sqlite://', echo=False)


class Student(Base):
    __tablename__ = 'student'
    id = Column(Integer, primary_key=True)
    name = Column(String)


Base.metadata.drop_all(engine)
Base.metadata.create_all(engine)
Session = sessionmaker(engine)
session = Session()


session.add(Student(name='foo'))

session.commit()


class Myclass(object):
    column = Student.name

    def test(self):
        print session.query(Student.id, Student.name).filter(self.__class__.column == 'foo').all()  # does not raise
        print session.query(Student.id, Student.name).filter(self.column == 'foo').all()  # raises error


my_class = Myclass()

my_class.test()

The error that is raised is:

AttributeError: 'Myclass' object has no attribute '_sa_instance_state'

Comments (4)

  1. Mike Bayer repo owner

    Student.name is a Python descriptor so it only works when associated with its own class. You need to wrap this into a @property:

    class Myclass(object):
        @property
        def column(self):
            return Student.name
    
        def test(self):
            self.column == 'foo'
    

    I can accept PRs that try to make a nicer error message but that's about it.

  2. Log in to comment