只需添加一个_xp 列定义,它映射到表中的xp 列,并使用常规@property 对象来实现您的设置器逻辑:
class Character(Base):
__tablename__ = 'character'
id = Column(Integer, primary_key=True)
level = Column(Integer)
_xp = Column('xp', Integer)
def __init__(self, level=0, xp=0):
self.level = level
self._xp = xp
@property
def xp(self):
return self._xp
@xp.setter
def xp(self, value):
self._xp = value
while self._xp >= self.xp_to_level_up():
self.level += 1
self._xp -= 100
见Naming Columns Distinctly from Attribute Names。
上面将实例上的_xp属性存储为character表中的xp,但是您的代码使用Character.xp属性间接读取和写入_xp的值。
您也可以使用@hybrid_property;这就像上面使用的property,但也允许您在查询过滤器中使用Character.xp:
from sqlalchemy.ext.hybrid import hybrid_property
class Character(Base):
__tablename__ = 'character'
id = Column(Integer, primary_key=True)
level = Column(Integer)
_xp = Column('xp', Integer)
def __init__(self, level=0, xp=0):
self.level = level
self._xp = xp
@hybrid_property
def xp(self):
return self._xp
@xp.setter
def xp(self, value):
self._xp = value
while self._xp >= self.xp_to_level_up():
self.level += 1
self._xp -= 100
现在您可以使用session.query(Character).filter(Character.xp > 42) 和其他此类过滤查询,而不必使用Character._xp。
如果你想对你的角色进行批量更新,你可能需要include a update_expression implementation 告诉 SQLAlchemy 如何为UPDATE 生成一个SET 表达式;除了调整 XP 之外,也许还可以使用 CASE 表达式来处理关卡更新。