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

使用psycopg2批量插入DataFrame报错:'dict'对象不支持索引

解决psycopg2批量插入DataFrame时的两个错误

Hey there! Let's break down why you're hitting those errors and get your bulk insert working smoothly.

先拆解你遇到的两个问题

  • "string index out of range":这个错误是因为你直接把整个DataFrame传给了execute_values的argslist参数。psycopg2.extras.execute_values期望argslist是可迭代的记录集合(比如元组列表、列表列表),而不是DataFrame对象本身。当它尝试按字符串索引去读取DataFrame时,自然会触发报错。
  • "'dict' object does not support indexing":当你用dataframe.to_dict(orient='records')得到字典列表后,execute_values默认的模板是按位置索引(比如%s)取值,但字典是键值对结构,没法用[0]、[1]这种索引方式访问,所以就出现了这个错误。

两种靠谱的解决方案

方案1:用列表列表作为输入(最简单直接)

把DataFrame转换成列表的列表,让execute_values可以直接按位置匹配列:

import psycopg2
from psycopg2 import sql
from psycopg2.extras import execute_values
import pandas as pd

# 假设你已经有cur(游标)、entity(目标表名)、column_names(列名列表)、dataframe(待插入的DataFrame)
try:
    # 将DataFrame转为列表的列表,每个子列表对应一行数据
    records = dataframe.to_numpy().tolist()
    
    execute_values(
        cur=cur,
        sql=sql.SQL("INSERT INTO {table_name} ({columns}) VALUES %s").format(
            table_name=sql.Identifier(entity),
            columns=sql.SQL(', ').join(map(sql.Identifier, column_names))
        ),
        argslist=records,
        page_size=500
    )
    # 务必提交事务,否则数据不会持久化到数据库
    cur.connection.commit()
except Exception as error:
    print('ERROR: ' + str(error))
    # 出错时回滚事务,避免未完成的事务占用资源
    cur.connection.rollback()

方案2:用字典列表配合自定义模板

如果你想保留字典的键值对应关系(避免列顺序出错),可以自定义template参数来匹配字典的键:

import psycopg2
from psycopg2 import sql
from psycopg2.extras import execute_values
import pandas as pd

try:
    # 转为字典列表,每个字典对应一行数据的键值对
    records = dataframe.to_dict(orient='records')
    
    # 构造模板:每个列对应字典的键,格式为(%(col1)s, %(col2)s, ...)
    template = sql.SQL("({})").format(
        sql.SQL(', ').join([sql.SQL('%({})s').format(sql.Identifier(col)) for col in column_names])
    )
    
    execute_values(
        cur=cur,
        sql=sql.SQL("INSERT INTO {table_name} ({columns}) VALUES %s").format(
            table_name=sql.Identifier(entity),
            columns=sql.SQL(', ').join(map(sql.Identifier, column_names))
        ),
        argslist=records,
        template=template,
        page_size=500
    )
    cur.connection.commit()
except Exception as error:
    print('ERROR: ' + str(error))
    cur.connection.rollback()

关键提醒

  • 一定要记得提交事务,否则插入的数据只会停留在内存中,不会写入数据库。
  • 出错时最好回滚事务,避免未完成的事务占用数据库资源。
  • 使用sql.Identifier和sql.SQL构造SQL语句,能有效防止SQL注入,这是psycopg2官方推荐的安全写法。

内容的提问来源于stack exchange,提问作者Cam Westwood

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 13:47:35