列的属性行为(getter 和 setter),而不是正常的属性行为

Mar*_*nen 3 python sqlalchemy properties python-3.x

SQLAlchemy 是否支持这样的东西:

class Character(Base):
   __tablename__ = 'character'
   id = Column(Integer, primary_key=True)
   level = Column(Integer)

   @ColumnProperty(Integer)
   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

   def __init__(self, level=0, xp=0):
       self.level = level
       self._xp = xp
Run Code Online (Sandbox Code Playgroud)

其中idlevel、 和xp将存储到数据库中。所以基本上是一个Column属性,而不是属性。

Mar*_*ers 5

只需添加一个映射到表中列的_xp列定义,并使用常规对象来实现您的 setter 逻辑: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
Run Code Online (Sandbox Code Playgroud)

请参阅与属性名称不同的命名列

上面将_xp属性存储在实例上,如表xp中所示character,但您的代码使用该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
Run Code Online (Sandbox Code Playgroud)

现在您可以使用session.query(Character).filter(Character.xp > 42)和其他此类过滤查询,而不必使用Character._xp.

如果您想对角色进行批量更新,您可能必须包含一个update_expression实现来告诉 SQLAlchemy 如何生成;SET的表达式。除了调整 XP 之外,UPDATE也许还可以使用表达式来处理更新级别。CASE