SQLAlchemy混合表达式访问不同的行

时间:2015-09-24 11:26:05

标签: python sqlalchemy

我有以下数据模型:

class TS(Base):  # Parent
    __tablename__ = 'ts'
    id = Column(Integer, primary_key=True)
    inspection_data = relationship('ID', backref='ts', uselist=False)

class ID(Base):  # Child
    __tablename__ = 'ins' 
    id = Column(Integer, primary_key=True)
    created = Column(Date, default=datetime.datetime.utcnow(), nullable=False)
    next_inspection = Column(Date, unique=False, nullable=True)
    ts_id = Column(Integer, ForeignKey('ts.id'))

现在我想创建一个混合属性'status',告诉我next_inspection是否过期(即今天落后)

我解决了这个问题:

    @hybrid_property
    def status(self):
        now = datetime.datetime.utcnow().date()
        delta = self.next_inspection - now
        if delta.days > 30:
            return 3  # OK, next inspection far away
        elif delta.days > 0:
            return 2  # Next inspection getting close
        else:  # We are overdue
            return 1

这在类和实例级别都有效,这意味着我甚至可以使用status查询。为了工作,我不得不补充:

    @status.comparator
    def status(cls):
        return DateTimeComparator(cls.next_inspection)

class DateTimeComparator(Comparator):
    def __gt__(self, other):
        return self.__clause_element__() > other
    # same for __lt__, __eq__ etc

现在我的问题: 我没有像上面的例子那样返回状态的值1,2或3,而是希望返回存储在另一个表中的三个值中的一个,其中包含以下模型:

class IDStatusValues(Base):
    __tablename__ = 'ins_status_values'
   id = Column(Integer, primary_key=True)
   value = Column(Unicode, unique=True, nullable=True, info={})
   ID_id = Column(Integer, ForeignKey('ins.id'))

包含以下数据:

id | value
-----------
0  | 'OK'
1  | 'APPROACHING'
2  | 'OVERDUE'

那就是我想将状态方法更改为:

   @hybrid_property
    def status(self):
        now = datetime.datetime.utcnow().date()
        delta = self.next_inspection - now
        if delta.days > 30:
            return IDStatusValues.get(0)  # OK, next inspection far away
        elif delta.days > 0:
            return IDStatusValues.get(1)  # Next inspection getting close
        else:  # We are overdue
            return IDStatusValues.get(2)

但是我不明白我怎么能在这个函数里面查询。我承认到现在为止我只是在声明方面工作,并且在真正的SQL /富有表现力的sqlalchemy方面不是很有经验。

1 个答案:

答案 0 :(得分:1)

class TS(Base):  # Parent
    __tablename__ = 'ts'
    id = Column(Integer, primary_key=True)
    inspection_data = relationship('ID', backref='ts', uselist=False)`

class ID(Base):  # Child
    __tablename__ = 'ins'
    id = Column(Integer, primary_key=True)
    created = Column(Date, default=datetime.datetime.utcnow(), nullable=False)
    next_inspection = Column(Date, unique=False, nullable=True)
    ts_id = Column(Integer, ForeignKey('ts.id'))
    IDStatusValues = relationship('IDStatusValues') **# Add this relationship**

    @hybrid_property
    def status(self):
        now = datetime.datetime.utcnow().date()
        delta = self.next_inspection - now
        if delta.days > 30:
            return self.IDStatusValues.property.table.c.id == 0  # OK, next inspection far away
        elif delta.days > 0:
            return self.IDStatusValues.property.table.c.id == 1  # Next inspection getting close
        else:  # We are overdue
            return self.IDStatusValues.property.table.c.id == 2`

class IDStatusValues(Base):
    __tablename__ = 'ins_status_values'
    id = Column(Integer, primary_key=True)
    value = Column(Unicode, unique=True, nullable=True, info={})
    ID_id = Column(Integer, ForeignKey('ins.id'))`

session.query(ID).filter(ID.status).all()