使用pyodbc导入CSV至数据库:动态列数与单引号问题求助
解决pyodbc动态导入CSV的列数适配与单引号转义问题
问题场景
使用pyodbc导入CSV文件到数据库时,CSV列数不固定(有时5列,有时更多),原固定列数的插入代码无法适配;改为动态拼接SQL值列表时,又遇到含单引号的字符串导致SQL语法错误。
原固定列数代码
data = pd.read_csv(filename, delimiter='|',skipinitialspace=True) df = pd.DataFrame(data) for row in df.itertuples(): cursor.execute('INSERT INTO ' + table_name + column_list +'VALUES (?,?)',row.col1,row.col2)
动态尝试代码(存在单引号转义问题)
data = pd.read_csv(filename, delimiter='|',skipinitialspace=True) df = pd.DataFrame(data) for row in df.itertuples(): list_value = list(row[1:]) list_value2 = str(list_value)[1:-1] cursor.execute('INSERT INTO ' + table_name + column_list +'VALUES (' + list_value2 + ')')
错误原因
直接将值列表转为字符串拼接进SQL语句,会让含单引号的字符串(如test's value2)破坏SQL语法结构,同时这种写法存在SQL注入风险。
解决方案
核心思路:继续使用pyodbc的参数化查询,动态生成占位符而非直接拼接值
参数化查询会由pyodbc自动处理字符串转义,同时完美适配动态列数:
- 动态生成占位符与SQL语句
data = pd.read_csv(filename, delimiter='|', skipinitialspace=True) df = pd.DataFrame(data) # 动态生成与列数匹配的占位符(?) placeholders = ', '.join(['?'] * len(df.columns)) # 若column_list也需要动态生成(适配CSV列名) column_list = f'({", ".join(df.columns)})' # 构造完整SQL sql = f'INSERT INTO {table_name} {column_list} VALUES ({placeholders})' # 逐行插入,使用参数化传递值 for row in df.itertuples(index=False): # index=False排除DataFrame索引列 cursor.execute(sql, row)
- 关键说明
- 占位符
?的数量与CSV列数完全匹配,无需手动修改 - 参数化查询会自动处理单引号、特殊字符的转义,不会出现语法错误
- 避免了SQL注入风险,比手动拼接值更安全
内容的提问来源于stack exchange,提问作者Southsun1
相关产品推荐
相关产品推荐

