- edited description
Hybrid attributes are under wrong name in result objects
When querying hybrid property it uses underlying column name instead of hybrid property name as attribute name in result object.
So code bellow (please note the commented line on the bottom):
from sqlalchemy import Integer, Column
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy.orm import sessionmaker, scoped_session
from sqlalchemy.types import TypeDecorator, Unicode, UnicodeText
Base = declarative_base()
class SomeClass(Base):
__tablename__ = 'some_table'
id = Column(Integer(), primary_key=True)
raw_foo = Column('foo', Integer(), nullable=False, default=0)
@hybrid_property
def foo(self):
if False: # some conditional code
return self.raw_foo * 10
return self.raw_foo
@foo.expression
def foo(cls):
return cls.raw_foo
@foo.setter
def foo(self, value):
self.raw_foo = value
engine = create_engine('sqlite://', echo=True)
Session = scoped_session(sessionmaker(bind=engine))
session = Session()
Base.metadata.create_all(engine)
session.commit()
session.add_all([
SomeClass(id=1, foo=1),
SomeClass(id=2, foo=10),
SomeClass(id=3, foo=30),
])
session.commit()
q = session.query(SomeClass.id, SomeClass.foo)
item = q.first()
# the commented line will work so apparently it uses
# underlying column as a name:
# print item.raw_foo
print item.foo
Will crash like this:
Traceback (most recent call last):
File "/home/virhilo/sqlalchemy_hybrids_error.py", line 47, in <module>
print item.foo
AttributeError: 'result' object has no attribute 'foo'
It happens on 1.0.8, 0.9.7 and latest from git (1.1.0b1)
Comments (7)
-
reporter -
reporter - edited description
-
reporter - edited description
-
repo owner - changed status to resolved
there's no special magic here, have your expression label it as desired:
@foo.expression def foo(cls): return cls.raw_foo.label('foo')
-
reporter Thanks:)
-
repo owner consider that lots of users expect the semantics of the returned SQL expression to stay the same rather than being automatically modified. But also, hybrids are just Python descriptors in the first place, which are not provided any means of knowing what attribute name they are accessed under, so some kind of explicit "name" parameter would be needed in any case, unless you did some kind of scanning of the class after it's declared and re-decorated all the hybrids with another decorator that provides labeling.
-
reporter Yeah, I misunderstood your previous comment initially, then edited mine as thought I was quick enough, sorry for messing.
- Log in to comment