SQLAlchemy:声明性MIXIN类中的getter/setter
我正在尝试为一个混合类定义简单的获取器和设置器方法,这个类我打算用在我的数据库结构中:
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
当我尝试运行这个例子时,出现了以下错误:
sqlalchemy.exc.InvalidRequestError: 映射器属性(比如 deferred、column_property()、relationship() 等)必须在声明性混合类中作为 @declared_attr 可调用对象来声明。
我的代码几乎是从 SQLAlchemy 声明式教程 复制过来的,唯一的不同是这个属性/同义词是在一个混合类中声明的。把 "@declared_attr" 装饰器加到现有的装饰器前面或后面并没有改变任何东西。
我该如何解决这个问题呢?
2 个回答
-1
@contact.setter
def contact_id(self, contact_id):
if (contact_id is None):
raise ValueError('contact_id can only be a uuid string')
if not isinstance(contact_id, str):
raise TypeError('contact_id is not a string')
self._contact_id = contact_id
使用一个设置器,上面的代码可以抛出比PyAlchemy更清晰的错误信息。
如果可以的话,你也可以选择在生产环境中优雅地处理这个错误。
14
也许可以把 attr()
创建成一个用 @declared_attr
装饰的类方法,这样它就可以返回一个同义词了?
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))