Python操作PostgreSQL插入执行成功但无数据写入问题求助
问题排查及解决方案
- df列名取值错误
你给出的df结构只有From、To两列,但代码中用row.station_from_code、row.station_to_code取值,实际你应该用row['From']、row['To']获取对应站点值。如果取值得到的是空值/NaN,会导致后续关联查询匹配不到任何数据,插入0行且无报错。
- df列名取值错误
- 插入目标表名未替换
代码中insert into table的table是SQL语法占位符,你需要替换为实际要写入的目标表名,大概率为你后续判断重复用的tsp_ams_navigation_route。如果未替换,要么写入了名为table的其他表,要么语句执行异常(因table是SQL关键字)。
- 插入目标表名未替换
- 数据库函数不兼容
PostgreSQL没有内置newid()函数,你需要替换为PostgreSQL支持的UUID生成函数:
- PG13及以上版本:用
gen_random_uuid() - 低版本需要先加载uuid-ossp扩展:
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";,再用uuid_generate_v4()
如果使用了不兼容的函数,语句执行失败也会导致无数据写入。
- 数据库函数不兼容
- 关联查询无匹配结果
你的插入逻辑是INSERT ... SELECT,只有SELECT子句返回结果时才会实际写入数据。你可以单独拿一组测试值(比如A、B)执行SELECT部分的SQL,验证是否有返回:
- 关联查询无匹配结果
SELECT ds_dep.station_code AS station_from_code, ds_arr.station_code AS station_to_code, ds_dep.icao_code AS station_from_icao_code, ds_arr.icao_code AS station_to_icao_code FROM dictionary ds_dep JOIN dictionary ds_arr ON ds_dep.station_code = 'A' AND ds_arr.station_code = 'B' AND ds_dep.delete_ts IS NULL AND ds_arr.delete_ts IS NULL
无返回的常见原因:字典表无对应站点记录、站点已被软删除(delete_ts非空)、大小写不匹配(PostgreSQL字符串大小写敏感)。
- 路由已存在被过滤
NOT EXISTS条件会过滤掉目标表中已存在的、未被软删除的同方向路由。你可以提前查询tsp_ams_navigation_route表,确认是否已经存在A->B、B->A的有效记录,存在的话不会重复插入。
- 路由已存在被过滤
- 连接环境不匹配
确认Python代码连接的数据库地址、库名、schema和你手动查询的环境完全一致,避免出现连测试库写数据、查生产库看结果的低级错误。
- 连接环境不匹配
优化建议
你可以在cursor.execute后增加插入行数判断,避免打印错误的成功提示:
cursor.execute(你调整后的SQL语句, (row['From'], row['To'], row['From'], row['To'])) affected_rows = cursor.rowcount if affected_rows > 0: print(f'ROUTES inserted {row["From"]}-{row["To"]}') else: print(f'ROUTES not inserted: {row["From"]}-{row["To"]} 无匹配字典或已存在') conn.commit()
内容的提问来源于stack exchange,提问作者Anakin Skywalker
相关产品推荐
相关产品推荐

