【问题标题】:Setter for a SQLAlchemy hybrid_property that queries from a joined table从连接表查询的 SQLAlchemy hybrid_property 的设置器
【发布时间】:2016-05-10 09:12:54
【问题描述】:

我正在尝试使用 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 做一个设置器来做到这一点。这是否违反了 ORM 的设计,因为 setter 的定义取决于 Status 表中存在的当前行?

【问题讨论】:

    标签: python properties sqlalchemy


    【解决方案1】:

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

    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'
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-10
      • 2018-06-18
      • 2019-12-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多