字段可为None时如何使用timedelta在SQLAlchemy中执行过滤查询
报错根因
你的报错发生在Python代码执行阶段,还没到SQL查询的执行环节:当PlayerAt实例的birth_date属性为None时,self.birth_date - dt.timedelta(weeks=4)这个表达式会直接触发类型错误,和后续传入的SQL函数没有关系。
你之前尝试用sa.func.IF的写法不生效,原因也在这里:self.birth_date是当前Python实例的属性值,不是SQL表达式中的字段,它的计算逻辑是在Python端完成后再传入SQL过滤器的,判断逻辑根本不会传递到SQL层的IF函数中。
修复方案
根据你的业务需求可以选择两种处理方式:
方案1:birth_date为空时直接返回空结果
如果业务逻辑要求只有PlayerAt实例有生日信息时才查询匹配的PlayerOc记录,空生日时直接返回空列表:
def return_player_oc_records(self): # 提前在Python层判断空值,避免后续时间运算报错 if self.birth_date is None: return [] 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)) return qry.all()
方案2:birth_date为空时忽略该过滤条件
如果业务逻辑要求空生日时返回所有PlayerOc记录,可以动态拼接过滤条件:
def return_player_oc_records(self): session = sa.orm.object_session(self) qry = session.query(PlayerOc) qry = qry.outerjoin(PlayerAt) # 仅当生日非空时添加时间过滤条件 if self.birth_date is not None: qry = qry.filter(PlayerOc.birth_date >= self.birth_date - dt.timedelta(weeks=4)) return qry.all()
内容的提问来源于stack exchange,提问作者Jossy
相关产品推荐
相关产品推荐

