从连接表查询的SQLAlchemy hybrid_property的Setter

时间:2016-02-01 19:28:18

标签: python properties sqlalchemy

我正在尝试使用SQLAlchemy中的一组状态来建模任务。我有以下内容:

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy.orm import relationship, backref

Base = declarative_base()

class Task(Base):
    __tablename__ = 'task'

    statusId = Column(Integer, ForeignKey('status.id'))
    status = relationship('Status', backref=backref('status'), lazy='joined')

    @hybrid_property
    def statusName(self):
        return self.status.name

class Status(Base):
    __tablename__ = 'status'

    id = Column(Integer, primary_key=True)
    name = Column(String(32), unique=True)

状态表填充在数据库中并且是相当静态的:

+----+--------------+
| id | name         |
+----+--------------+
|  1 | unassigned   |
|  2 | pending      |
|  3 | working      |
|  4 | failed       |
|  5 | done         |
+----+--------------+

我希望能够做的是按名称而不是id来引用状态名称。因此,当任务的状态发生变化时,我想写task.statusName = 'working'而不是task.statusId = 3。我不确定如何为statusName设置这样做的setter。这是否违反ORM的设计,因为setter的定义取决于Status表中当前的行?

1 个答案:

答案 0 :(得分:0)

您可以稍微更改数据库结构以达到预期效果。看来你在状态上有一个自然的关键。该名称实际上是主键。

class Task(Base):
    __tablename__ = 'task'

    status = Column(String(32), ForeignKey('status.name'))

class Status(Base):
    __tablename__ = 'status'

    name = Column(String(32), primary_key=True)

然后您可以轻松地设置状态:

task = Task()
task.status = 'error'

如果状态不可用,这也会引发异常,因为仍然存在外键约束。