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

使用SQLAlchemy将CSV文件导入PostgreSQL时遭遇非预期的double precision类型错误

问题诊断与解决方案

从你的错误信息和描述来看,这个问题的根源大概率是CSV文件列错位或者pandas自动类型推断不一致导致的,下面一步步分析并给出解决办法:

1. 优先排查CSV文件的格式问题

错误提示里提到invalid input syntax for type double precision: "30.580*",而这个带*的值本应存入text类型的sec_thr列,但实际上它被传到了decimal类型的数值列中。这种情况通常意味着:

  • 第二个CSV文件的第4行存在格式错误:比如遗漏了逗号、或者有包含逗号的未转义文本,导致列整体错位,把sec_thr列的带*值挤到了后面的数值类型列里。
  • 两个CSV文件的表头顺序不一致:第一个文件的列顺序和表结构匹配,但第二个文件的列顺序变了,导致数据对应到错误的列。

排查步骤:

  • 用文本编辑器打开第二个CSV文件,对比表头和gp_times表的列顺序,确保完全一致。
  • 查看第4行数据(注意区分表头行和数据行),数一下列的数量是否和表头一致,有没有明显的格式错误(比如某个字段里的逗号没被引号包裹)。

2. 强制指定列数据类型,避免pandas自动推断错误

即使CSV格式没问题,pandas的自动类型推断可能在不同文件间出现偏差:比如第一个CSV的sec_thr列全是带*的字符串,pandas推断为object(对应SQL的text);但第二个CSV里该列可能先出现了纯数字值,导致pandas推断为float类型,后续遇到带*的值时,虽然能存入DataFrame,但to_sql时会尝试把它作为数值插入,引发错误。

解决办法:在pd.read_csv时强制指定每一列的数据类型,和表结构严格对应:

# 定义和表结构匹配的dtype字典
csv_dtype = {
    'index': str,
    'month': str,
    'day': str,
    'yr': int,
    'lge': str,
    'rnd': int,
    'session': str,
    'trk': str,
    'pos': str,
    'rdr_num': int,
    'f_name': str,
    'l_name': str,
    'nat': str,
    'team': str,
    'manu': str,
    'num_of_laps': int,
    'run_num': int,
    'f_tire': str,
    'r_tire': str,
    'laps_on_f': int,
    'laps_or_r': int,
    'lap_num': int,
    'lap_time': str,
    'lap_seconds': float,
    'lap_valid': bool,
    'pit': bool,
    'sec_one': str,
    'one_seconds': float,
    'one_valid': bool,
    'sec_two': str,
    'two_seconds': float,
    'two_valid': bool,
    'sec_thr': str,
    'thr_seconds': float,
    'thr_valid': bool,
    'sec_four': str,
    'four_seconds': float,
    'four_valid': bool,
    'avg_spd': str
}

# 在read_csv时指定dtype
df = pd.read_csv(f, dtype=csv_dtype)

这样可以确保pandas不会错误推断列类型,所有文本列都被强制识别为字符串,避免插入时类型不匹配。

3. 额外的验证步骤

为了进一步确认问题,可以在循环里添加临时验证,提前发现异常:

for file in fLis:
    with open(file, "r", encoding="utf-8") as f:
        df = pd.read_csv(f, dtype=csv_dtype)
        print(file)
        # 检查df的列顺序和表结构是否一致
        table_columns = [col.strip() for col in createTimesTable.split('(')[1].split(')')[0].split('\n')[1:-1]]
        table_columns = [col.split()[0] for col in table_columns]
        if list(df.columns) != table_columns:
            print(f"⚠️ 列顺序不匹配!文件{file}的列顺序:{list(df.columns)}")
            print(f"表结构列顺序:{table_columns}")
            continue
        # 检查sec_thr列是否有不符合格式的值
        invalid_sec_thr = df[~df['sec_thr'].astype(str).str.match(r'^\d+\.\d+\*?$')]
        if not invalid_sec_thr.empty:
            print(f"⚠️ 文件{file}中sec_thr列存在异常值:{invalid_sec_thr['sec_thr'].tolist()}")
        # 执行插入
        df.to_sql("gp_times", con = engine, if_exists = "append", index = False)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 19:28:15