我正在尝试为我打算在我的数据库模式中使用的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:Mapper属性(即deferred,column_property(),relationship()等)必须在声明性mixin类中声明为@declared_attr callables。
我的代码几乎是SQLAlchemy Declarative Tutorial的1:1副本,唯一的区别是属性/同义词是在Mixin类中声明的。将“@declared_attr”装饰器附加或添加到现有装饰器不会改变任何内容。
如何解决这种情况?
答案 0 :(得分:13)
也许创建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))
答案 1 :(得分:0)
@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
使用 setter 上面的代码可以抛出更清晰的错误 比 PyAlchemy 可以扔给你的东西更多。
如果可能,您也可以选择优雅地处理生产中的错误。