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

如何在SQLAlchemy的insert_on_conflict_nothing中自动获取主键?

解决方案

错误原因

你在自定义方法中直接访问的table是Pandas内部的SQLTable实例,而非SQLAlchemy的Table对象,所以它没有primary_key属性。必须获取对应的SQLAlchemy Table实例才能读取主键信息。

方法一:直接调用SQLTable内部的SQLAlchemy Table

修改自定义方法,访问SQLTable的table属性(该属性对应SQLAlchemy的Table对象)来获取主键:

def insert_on_conflict_nothing(table, conn, keys, data_iter):
    data = [dict(zip(keys, row)) for row in data_iter]
    # 获取SQLAlchemy Table实例
    sa_table = table.table
    # 提取主键列名
    pkey = [pk_col.name for pk_col in sa_table.primary_key.columns.values()]
    stmt = insert(sa_table).values(data).on_conflict_do_nothing(index_elements=pkey)
    result = conn.execute(stmt)
    return result.rowcount

方法二:手动加载SQLAlchemy Table(更可靠)

如果方法一出现表结构未加载的问题,可以在自定义方法内主动从数据库加载表结构,确保能正确获取主键:

from sqlalchemy import Table, MetaData

def insert_on_conflict_nothing(table, conn, keys, data_iter):
    data = [dict(zip(keys, row)) for row in data_iter]
    # 从数据库加载表结构
    meta = MetaData()
    sa_table = Table(
        table.name,
        meta,
        schema=table.schema,
        autoload_with=conn.engine
    )
    # 提取主键列名
    pkey = [pk_col.name for pk_col in sa_table.primary_key.columns.values()]
    stmt = insert(sa_table).values(data).on_conflict_do_nothing(index_elements=pkey)
    result = conn.execute(stmt)
    return result.rowcount

注意事项

  • 确保数据库账号拥有读取表结构的权限,否则方法二中的autoload_with会失败
  • 两种方法都支持多列主键,你的单列主键场景完全适用
  • 无需在多个插入函数中硬编码主键列名,实现了自动适配不同表的需求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 00:27:16