You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas to_sql写入PostgreSQL时数据带{}花括号问题解决方案

问题产生原因

PostgreSQL中字段值被{}花括号包裹是数组类型的标准存储表现,该问题由写入时的数据类型不匹配导致:

  1. 代码中re.findall()的返回值固定为Python列表类型,即使仅匹配到1个结果,也会返回单元素列表(即控制台打印的['$3.291']格式)。直接将该列表作为价格字段值写入DataFrame时,pandas结合SQLAlchemy写入PostgreSQL的过程中,会自动将Python列表映射为PostgreSQL数组类型(TEXT[]或NUMERIC[]),数组类型的查询输出默认以{}包裹内部元素。
  2. DataFrame初始化逻辑存在缺陷:初始给价格列传入的是字符串类型测试值"price",后续循环写入时又传入列表类型值,列类型混杂会干扰pandas的类型推断逻辑,提升类型映射错误概率。
  3. 代码存在两处冗余/不规范写法:df.head()仅做打印输出无赋值操作,不会对数据产生实际修改;df.to_sql()执行完成后才新建psycopg2连接查询数据,若to_sql传入的conn是psycopg2原生连接而非SQLAlchemy引擎连接,会进一步提高类型推断的出错概率。
规避与修复方法
  • 提取价格时将列表转为标量值,禁止直接存入re.findall()返回的列表。由于单条商品数据仅对应一个价格,直接取匹配结果的首元素即可,同时增加兜底逻辑避免无匹配结果时触发索引报错:
numbers = re.findall(r'(?:[\£\$\€]{1}[,\d]+.?\d*)', justText)
# 取首个匹配到的价格,无匹配结果时赋值为空
price = numbers[0] if numbers else None

后续DataFrame赋值时传入处理后的标量price,替换原来的numbers参数:

df.loc[justText[:pos]] = [justText[:pos], price]
  • 修正DataFrame初始化逻辑,删除无意义的测试占位行,直接定义空表明确列结构,避免脏数据和类型混乱:
# 替换原来带测试数据的初始化代码
df = pd.DataFrame(columns=['Product Name', 'Product Price'])
  • 写入数据库前强制指定列类型,从根源避免类型自动推断偏差。如果需要保留带货币符号的价格文本,可将价格列强制转为字符串类型;如果需要后续做数值计算,可进一步清洗掉货币符号、千分位分隔符后转为浮点数:
# 保留文本格式时使用
df['Product Price'] = df['Product Price'].astype(str)
  • 规范数据库连接使用:df.to_sql()方法要求传入SQLAlchemy创建的引擎连接,不要直接传入psycopg2生成的原生连接,避免类型映射逻辑异常。

内容的提问来源于stack exchange,提问作者Guilherme Zago

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 04:03:29