SQLAlchemy针对日期字段空值的小于等于查询问题
处理SQLAlchemy中日期字段空值的小于等于查询问题
嘿,我来帮你搞定这个查询的问题。首先得指出你当前写法里的一个关键坑:用MOTExpiry != None来排除空值其实在SQL层面是不生效的,这是个很容易踩的SQL基础陷阱。
问题根源
在SQL的逻辑里,NULL和任何值做比较(包括!=、=)都会返回UNKNOWN,而不是True或False。所以你写的MOTExpiry != None会被转换成SQL的MOTExpiry <> NULL,这个条件根本筛选不掉任何空值行——哪怕表里有MOTExpiry为空的数据,也不会被这个条件排除。
正确的写法
SQLAlchemy专门提供了处理空值判断的方法:isnot(None),它会被正确转换成SQL里的IS NOT NULL,这才是符合SQL规范的非空判断方式。修正后的查询代码如下:
from sqlalchemy import and_ import datetime now = datetime.datetime.now() car = session.query(CarLicenceData).filter(and_( CarLicenceData.MOTExpiry <= now.date(), CarLicenceData.MOTExpiry.isnot(None), # 替换成isnot(None) CarLicenceData.userIdOwner == 'eu-west-1:97923fc8-2b0f-4caa-b6b9-7974941073ec' )).one()
额外场景补充(如果需要包含空值)
要是你的需求是同时匹配MOTExpiry过期或者为空的行,可以用or_把空值的情况整合进来,代码如下:
from sqlalchemy import and_, or_ import datetime now = datetime.datetime.now() car = session.query(CarLicenceData).filter(and_( or_( CarLicenceData.MOTExpiry <= now.date(), CarLicenceData.MOTExpiry.is_(None) # 判断为空用is_(None) ), CarLicenceData.userIdOwner == 'eu-west-1:97923fc8-2b0f-4caa-b6b9-7974941073ec' )).one()
你当前的查询能返回结果,大概率是因为符合userIdOwner条件的数据里,MOTExpiry本来就没有空值,但换成规范的isnot(None)写法后,才能确保在所有数据场景下都正确过滤空值。
内容的提问来源于stack exchange,提问作者Dambre
相关产品推荐
相关产品推荐

