解决PostgreSQL查询结果中空数组无法写入Excel的ValueError问题
解决PostgreSQL查询结果中空数组无法写入Excel的问题
你遇到的这个错误很典型——openpyxl没办法直接把Python的空列表(对应PostgreSQL里的空数组{})写入Excel单元格。咱们可以从修改SQL查询或者在Python代码里处理结果两个方向来解决,下面给你具体的方案:
方案一:修改SQL查询,直接返回适合Excel的格式
既然memberof是数组类型,我们可以在查询时就把它转成逗号分隔的字符串,空数组直接转为空字符串,这样拿到的结果就能直接写入Excel了。
修改后的查询语句(简洁版):
SELECT r.rolname, r.rolsuper, r.rolinherit, r.rolcreaterole, r.rolcreatedb, r.rolcanlogin, r.rolconnlimit, r.rolvaliduntil, -- 自动把空数组转为空字符串,非空数组转为逗号分隔的字符串 ARRAY_TO_STRING(ARRAY(SELECT b.rolname FROM pg_catalog.pg_auth_members m JOIN pg_catalog.pg_roles b ON (m.roleid = b.oid) WHERE m.member = r.oid), ',') as memberof , r.rolreplication , r.rolbypassrls FROM pg_catalog.pg_roles r WHERE r.rolname !~ '^pg_' ORDER BY 1;
ARRAY_TO_STRING处理空数组时会直接返回空字符串,完全满足需求,不用额外加判断逻辑。
方案二:在Python代码中处理查询结果
如果不想修改SQL,也可以在代码遍历查询结果时,把数组类型的字段(比如memberof对应的列表)转成字符串,空列表直接替换成空字符串。
修改你代码中遍历records的部分:
for row in records: # 处理每一行的元素,适配Excel的写入要求 processed_row = [] for item in row: if isinstance(item, list): # 空列表转空字符串,非空列表转逗号分隔的字符串 processed_row.append(','.join(item) if item else '') else: # 其他类型直接保留(布尔值、整数等openpyxl都能处理) processed_row.append(item) ws.append(processed_row)
这样处理后,空数组对应的[]就变成了空字符串,非空数组会变成类似role1,role2的格式,都能正常写入Excel。
额外小提示
除了数组,PostgreSQL返回的布尔值f/t、空时间戳等,你也可以根据需要在代码里统一调整显示格式,比如把f转成False,t转成True,让Excel里的内容更易读。
内容的提问来源于stack exchange,提问作者brvxavier
相关产品推荐
相关产品推荐

