SQLModel如何正确实现字段NULL值过滤查询
SQLModel 查询字段为NULL值记录的正确方案
问题背景
需要实现等价于以下SQL的查询逻辑,查询所有age字段为NULL的hero记录:
SELECT * FROM hero WHERE age IS NULL
直接写select(Hero).where(Hero.age != None)虽然能正常运行,但会触发PEP 8 E711告警(提示和None比较应该用is/is not);改成select(Hero).where(Hero.age is None)又无法达到预期效果,会生成错误的SQL语句:
SELECT * FROM hero WHERE 0 = 1
问题原因
Python的is关键字用于判断两个对象的内存身份是否一致,这个逻辑无法被SQLModel的列属性重载。执行Hero.age is None时,会直接在Python运行时得到布尔值False,最终被SQL解析器转换为永远不成立的0=1条件,自然无法得到预期结果。
正确实现方式
有两种标准写法,都可以正确生成IS NULL的SQL逻辑,且不会触发PEP8告警:
- 写法1:使用列对象内置的
is_()方法(最常用)
from sqlmodel import select # 查询age为NULL的记录 stmt = select(Hero).where(Hero.age.is_(None)) # 对应查询age非空的无告警写法 stmt = select(Hero).where(Hero.age.is_not(None))
- 写法2:使用SQLModel内置的
null构造方法配合==判断
from sqlmodel import select, null stmt = select(Hero).where(Hero.age == null())
注:
==运算符可以被SQLModel的列属性重载,会被正确翻译为SQL层面的IS NULL逻辑,不会触发E711告警——E711规则仅针对Python代码中直接和None关键字做==/!=比较的场景。
内容的提问来源于stack exchange,提问作者Keerthi
相关产品推荐
相关产品推荐

