I am trying to define simple getter/setter methods for a mixin class that I intend to use in my database schema:
from sqlalchemy import Column, Integer, create_engine
from sqlalchemy.orm import synonym, scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base, declared_attr
engine = create_engine('sqlite:///')
Base = declarative_base(bind=engine)
Session = scoped_session(sessionmaker(bind=engine))
class Mixin(object):
_attr = Column('attr', Integer)
@property
def attr(self):
return self._attr
@attr.setter
def attr(self, value):
self._attr = value
attr = synonym('_attr', descriptor=attr)
class DummyClass(Base, Mixin):
__tablename__ = 'dummy'
id = Column(Integer, primary_key=True)
Base.metadata.create_all()
if __name__ == '__main__':
session = Session()
testobj = DummyClass()
session.add(testobj)
testobj.attr = 42
assert testobj.attr == 42
When I try to run this example, I get the following error:
sqlalchemy.exc.InvalidRequestError: Mapper properties (i.e. deferred,column_property(), relationship(), etc.) must be declared as @declared_attr callables on declarative mixin classes.`
My code is almost a 1:1 copy from the SQLAlchemy Declarative Tutorial, with the only difference that the property/synonym is declared in a Mixin class. Appending or prepending the "@declared_attr" decorator to the existing decorators does not change anything.
How do I resolve this situation?
Perhaps create the attr()
as an @declared_attr
-decorated class method which returns the synonym?
class Mixin(object):
_attr = Column('attr', Integer)
def get_attr(self):
return self._attr
def set_attr(self, value):
self._attr = value
@declared_attr
def attr(cls):
return synonym('_attr', descriptor=property(cls.get_attr, cls.set_attr))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With