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

Python脚本导入多列CSV到MySQL时出现参数不足错误的求助

Python脚本导入多列CSV到MySQL时出现参数不足错误的求助

嗨,别担心,这个问题其实挺常见的,咱们一步步来解决它!

首先看你遇到的Not enough parameters for the SQL statement错误,核心原因是你传给SQL的参数数量和语句里的%s数量不匹配。你现在的代码里,for row in f循环拿到的row是一整行的字符串(比如"192.168.1.16,192.168.1.255,..."),然后你把它作为单个参数(row,)传给execute方法,但你的SQL语句里有84个%s,自然就会报错参数不够啦。

接下来咱们一步步修正代码:


1. 正确读取CSV内容,拆分每一行的字段

不要直接遍历文件行,而是用Python内置的csv模块来读取,它会自动帮你把每一行拆分成对应的字段列表,还能处理可能的特殊情况(比如字段里包含逗号的场景)。

2. 跳过CSV的表头(如果有的话)

如果你的实际CSV第一行是表头(比如src_ip,dst_ip,...),记得要跳过,不然会把表头字符串插入到数值类型的字段里,导致新的类型不匹配错误。

3. 替换SQL语句里的'%s'为%s,避免SQL注入风险

你现在的SQL里写的是'%s'(带单引号),但用参数化查询的时候,MySQL连接器会自动处理字符串的引号,不需要手动加,手动加反而会导致参数解析错误,还存在SQL注入的安全隐患。

4. 数据类型转换

你的MySQL表字段有INT、FLOAT、DATETIME等类型,从CSV读出来的都是字符串,需要把对应的字段转换成正确的类型,不然插入的时候可能会报错类型不兼容。


修正后的完整代码

import mysql.connector
import csv
from datetime import datetime

# 连接数据库
db = mysql.connector.connect(
    host="localhost",
    user="root",
    passwd="root",
    database="Apollo"
)
mycursor = db.cursor()

# 表创建函数(安装时调用)
def db_setup():
    create_table_sql = """
    CREATE TABLE NetworkLogs (
        id INT AUTO_INCREMENT PRIMARY KEY, 
        src_ip VARCHAR(15), 
        dst_ip VARCHAR(15), 
        src_port INT, 
        dst_port INT, 
        src_mac VARCHAR(17), 
        dst_mac VARCHAR(17), 
        protocol INT, 
        timestamp DATETIME, 
        flow_duration FLOAT, 
        flow_byts_s FLOAT, 
        flow_pkts_s FLOAT, 
        fwd_pkts_s FLOAT, 
        bwd_pkts_s FLOAT, 
        tot_fwd_pkts INT, 
        tot_bwd_pkts INT, 
        totlen_fwd_pkts INT, 
        totlen_bwd_pkts INT, 
        fwd_pkt_len_max FLOAT, 
        fwd_pkt_len_min FLOAT, 
        fwd_pkt_len_mean FLOAT, 
        fwd_pkt_len_std FLOAT, 
        bwd_pkt_len_max FLOAT, 
        bwd_pkt_len_min FLOAT, 
        bwd_pkt_len_mean FLOAT, 
        bwd_pkt_len_std FLOAT, 
        pkt_len_max FLOAT, 
        pkt_len_min FLOAT, 
        pkt_len_mean FLOAT, 
        pkt_len_std FLOAT, 
        pkt_len_var FLOAT, 
        fwd_header_len INT, 
        bwd_header_len INT, 
        fwd_seg_size_min INT, 
        fwd_act_data_pkts INT, 
        flow_iat_mean FLOAT, 
        flow_iat_max FLOAT, 
        flow_iat_min FLOAT, 
        flow_iat_std FLOAT, 
        fwd_iat_tot FLOAT, 
        fwd_iat_max FLOAT, 
        fwd_iat_min FLOAT, 
        fwd_iat_mean FLOAT, 
        fwd_iat_std FLOAT, 
        bwd_iat_tot FLOAT, 
        bwd_iat_max FLOAT, 
        bwd_iat_min FLOAT, 
        bwd_iat_mean FLOAT, 
        bwd_iat_std FLOAT, 
        fwd_psh_flags INT, 
        bwd_psh_flags INT, 
        fwd_urg_flags INT, 
        bwd_urg_flags INT, 
        fin_flag_cnt INT, 
        syn_flag_cnt INT, 
        rst_flag_cnt INT, 
        psh_flag_cnt INT, 
        ack_flag_cnt INT, 
        urg_flag_cnt INT, 
        ece_flag_cnt INT, 
        down_up_ratio FLOAT, 
        pkt_size_avg FLOAT, 
        init_fwd_win_byts INT, 
        init_bwd_win_byts INT, 
        active_max FLOAT, 
        active_min FLOAT, 
        active_mean FLOAT, 
        active_std FLOAT, 
        idle_max FLOAT, 
        idle_min FLOAT, 
        idle_mean FLOAT, 
        idle_std FLOAT, 
        fwd_byts_b_avg FLOAT, 
        fwd_pkts_b_avg FLOAT, 
        bwd_byts_b_avg FLOAT, 
        bwd_pkts_b_avg FLOAT, 
        fwd_blk_rate_avg FLOAT, 
        bwd_blk_rate_avg FLOAT, 
        fwd_seg_size_avg FLOAT, 
        bwd_seg_size_avg FLOAT, 
        cwe_flag_count INT, 
        subflow_fwd_pkts INT, 
        subflow_bwd_pkts INT, 
        subflow_fwd_byts INT, 
        subflow_bwd_byts INT
    )
    """
    mycursor.execute(create_table_sql)

# 插入数据到数据库
def db_post():
    csv_file_path = 'src/cicflowmeter/test1.csv'
    # 定义字段的类型转换函数,按顺序对应表的字段(除了自增的id)
    type_converters = [
        str, str, int, int, str, str, int,
        lambda x: datetime.strptime(x, '%Y-%m-%d %H:%M:%S'),
        float, float, float, float, float,
        int, int, int, int, float, float, float, float,
        float, float, float, float, float, float, float, float, float,
        int, int, int, int, float, float, float, float,
        float, float, float, float, float, float, float, float, float, float,
        int, int, int, int, int, int, int, int, int, int, int,
        float, float, int, int, float, float, float, float,
        float, float, float, float, float, float, float, float,
        int, int, int, int, int
    ]
    
    with open(csv_file_path, 'r') as f:
        csv_reader = csv.reader(f)
        # 如果你的CSV有表头,取消下面这行注释跳过表头
        # next(csv_reader)
        
        for row in csv_reader:
            # 转换每个字段的类型
            converted_row = [converter(val) for converter, val in zip(type_converters, row)]
            # 自动生成占位符,避免手动写84个%s
            placeholders = ', '.join(['%s'] * len(converted_row))
            query = f"""
            INSERT INTO NetworkLogs (
                src_ip, dst_ip, src_port, dst_port, src_mac, dst_mac, protocol, timestamp, 
                flow_duration, flow_byts_s, flow_pkts_s, fwd_pkts_s, bwd_pkts_s, tot_fwd_pkts, 
                tot_bwd_pkts, totlen_fwd_pkts, totlen_bwd_pkts, fwd_pkt_len_max, fwd_pkt_len_min, 
                fwd_pkt_len_mean, fwd_pkt_len_std, bwd_pkt_len_max, bwd_pkt_len_min, bwd_pkt_len_mean, 
                bwd_pkt_len_std, pkt_len_max, pkt_len_min, pkt_len_mean, pkt_len_std, pkt_len_var, 
                fwd_header_len, bwd_header_len, fwd_seg_size_min, fwd_act_data_pkts, flow_iat_mean, 
                flow_iat_max, flow_iat_min, flow_iat_std, fwd_iat_tot, fwd_iat_max, fwd_iat_min, 
                fwd_iat_mean, fwd_iat_std, bwd_iat_tot, bwd_iat_max, bwd_iat_min, bwd_iat_mean, 
                bwd_iat_std, fwd_psh_flags, bwd_psh_flags, fwd_urg_flags, bwd_urg_flags, fin_flag_cnt, 
                syn_flag_cnt, rst_flag_cnt, psh_flag_cnt, ack_flag_cnt, urg_flag_cnt, ece_flag_cnt, 
                down_up_ratio, pkt_size_avg, init_fwd_win_byts, init_bwd_win_byts, active_max, 
                active_min, active_mean, active_std, idle_max, idle_min, idle_mean, idle_std, 
                fwd_byts_b_avg, fwd_pkts_b_avg, bwd_byts_b_avg, bwd_pkts_b_avg, fwd_blk_rate_avg, 
                bwd_blk_rate_avg, fwd_seg_size_avg, bwd_seg_size_avg, cwe_flag_count, subflow_fwd_pkts, 
                subflow_bwd_pkts, subflow_fwd_byts, subflow_bwd_byts
            ) VALUES ({placeholders})
            """
            mycursor.execute(query, converted_row)
    db.commit()
    print("数据插入成功!")

db_post()

额外注意事项

  • 如果你CSV的第一行是表头,一定要取消代码里next(csv_reader)的注释,否则会把表头字符串插入到数值字段中,引发类型错误。
  • 代码里的类型转换逻辑确保了每个字段和MySQL表的类型匹配,比如把端口号转成INT、时间字符串转成datetime对象,避免插入时的类型不兼容问题。
  • 用csv.reader比直接遍历文件行更可靠,它能处理标准CSV格式的各种特殊情况。
  • 自动生成占位符的方式,避免了手动写84个%s的麻烦,也减少了写错的概率。

试试看这个修正后的代码,应该就能解决你的问题啦!如果还有其他报错,可以再告诉我具体的错误信息哦~

备注:内容来源于stack exchange,提问作者Ryan Casey

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.16 03:12:58