pyodbc查询PostgreSQL过滤bypass保留NULL值报42703错误排查
问题说明
使用pyodbc操作PostgreSQL执行查询语句时触发运行报错,相关信息如下:
- 字段逻辑:
bypass为后续新增字段,正常取值范围1~3,采集初期生成的历史行中该字段值为None(对应数据库NULL值) - 查询需求:过滤掉
bypass值为2的记录,同时保留bypass为None的历史数据
原实现代码:
currentPeak = cursor.execute("SELECT MAX(value) FROM table WHERE (year = 2022 AND month = 3 AND (bypass != 2 OR bypass == None));").fetchval() return currentPeak
触发报错:
pyodbc.ProgrammingError: ('42703', '[42703] ERROR: column "none" does not exist;\nError while executing the query (1) (SQLExecDirectW)')
报错根因
- SQL语法不支持
==作为相等判断符,相等判断统一使用= - 直接将Python的空值
None写在SQL语句中,会被数据库解析为标识符(列名),而非空值,因此触发"列none不存在"的报错。SQL中判断空值必须使用专用语法IS NULL/IS NOT NULL,不能用普通等值运算符判断。 - PostgreSQL中NULL值和任意值做
=、!=这类普通比较运算,返回结果都不为真,即使逻辑上想表达"不等于2",也不会匹配到NULL值的行,必须单独对空值做判断。
修正后代码
currentPeak = cursor.execute( "SELECT MAX(value) FROM table WHERE year = 2022 AND month = 3 AND (bypass != 2 OR bypass IS NULL);" ).fetchval() return currentPeak
可选简化写法:也可以使用
bypass IS DISTINCT FROM 2替代上述括号内的判断逻辑,该语法会自动将NULL值视为和2不相等,直接实现"排除值为2的行、保留其余所有行(含NULL值行)"的效果,对应SQL为:SELECT MAX(value) FROM table WHERE year = 2022 AND month = 3 AND bypass IS DISTINCT FROM 2;
内容的提问来源于stack exchange,提问作者BabaZuri
相关产品推荐
相关产品推荐

