【问题标题】:How to filter using timedelta when a field can be None?当字段可以为无时如何使用 timedelta 进行过滤?
【发布时间】:2021-12-24 11:37:16
【问题描述】:

我正在尝试在PlayerAt 表中创建一个方法,以根据使用timedelta 的过滤器从PlayerOc 表中选择记录。这是精简的课程:

class PlayerAt(Base):

    id_ = sa.Column(sa.Integer, primary_key=True)
    birth_date = sa.Column(sa.Date, index=True)

    def return_player_oc_records(self):
        session = sa.orm.object_session(self)
        qry = session.query(PlayerOc)
        qry = qry.outerjoin(PlayerAt)
        qry = qry.filter(PlayerOc.birth_date >= self.birth_date - dt.timedelta(weeks=4))
        recs = qry.all()
        return recs

但是,当我执行该方法时,我得到了错误:

TypeError: unsupported operand type(s) for -: 'NoneType' and 'datetime.timedelta'

这是因为某些PlayerAt 记录没有birth_date

我尝试将过滤器转换为:

qry = qry.filter(PlayerOc.birth_date >= sa.func.IF(self.birth_date != None, self.birth_date - dt.timedelta(weeks=4), None))

但是,我得到了同样的错误。

关于修复的任何想法?

【问题讨论】:

    标签: python mysql sqlalchemy


    【解决方案1】:

    你可以使用和

    qry = qry.filter((self.birth_date.isnot(None)) & (PlayerOc.birth_date >=  self.birth_date - dt.timedelta(weeks=4)))
    

    如果你不想保留生日,你可以使用或条件

    qry = qry.filter((self.birth_date.is_(None)) | (PlayerOc.birth_date >=  self.birth_date - dt.timedelta(weeks=4)))
    

    【讨论】:

    • 嘿。感谢您试一试。可悲的是,我在第一个选项中遇到了同样的错误:(
    • 更新到新方法
    • 对于没有 birth_date 的记录出现相同的错误,但现在对于那些有 birth_date - TypeError: unsupported operand type(s) for &: 'bool' and 'BinaryExpression' 的记录也会出现新错误
    • 刚刚更新。试试.isnot(None) 表达式而不是!= None。可能是版本问题。
    • 之前尝试过isnot :( 这给出了错误AttributeError: 'datetime.date' object has no attribute 'isnot'。我认为这个问题与我尝试使用从self 访问字段而不是使用直接使用类的单独查询
    【解决方案2】:

    想出了一个方法来使用DATEDIFF 来解决这个问题:

    qry = qry.filter(sa.func.datediff(PlayerOc.birth_date, self.birth_date) >= -28)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-16
      • 2020-01-07
      • 2020-03-23
      • 2021-01-24
      • 2016-12-14
      • 2014-01-27
      • 1970-01-01
      • 2018-11-03
      相关资源
      最近更新 更多