将CSV中NULL转为空值导入SQL Server时遇DataError问题求助
问题根源
错误核心原因:你将所有列的NULL统一替换为空字符串,但SQL Server表中存在非字符串类型列(如整数、小数、日期等),空字符串无法被数据库自动转换为这些类型的合法值,触发类型转换失败;而直接保留NULL时,pandas会将其转为SQL Server对应类型的空值,不会触发错误。
解决方案
1. 按列类型差异化处理空值
不要全局填充空字符串,仅对字符串类型列填充,非字符串列保留NaN(pandas会自动将NaN转为SQL的NULL):
@event.listens_for(engine, 'before_cursor_execute') def receive_before_cursor_execute(conn, cursor, statement, params, context, executemany): if executemany: cursor.fast_executemany = True for filename in os.listdir(directory): # 不强制所有列为str,让pandas自动推断数据类型 df = pd.read_csv(fl_path, header=0) # 筛选字符串类型列(object dtype) string_columns = df.select_dtypes(include=['object']).columns # 仅对字符串列填充空字符串 df[string_columns] = df[string_columns].fillna("") # 非字符串列的NaN会被to_sql转换为SQL NULL df.to_sql(table_name, con=engine, if_exists='append', index=False)
2. 手动指定列类型(按需使用)
如果必须在读取CSV时指定列类型,需分列指定而非全局设为str:
# 示例:根据SQL Server表结构定义列类型映射 dtype_mapping = { 'user_id': int, 'user_name': str, 'age': float, 'register_time': 'datetime64[ns]' } df = pd.read_csv(fl_path, header=0, dtype=dtype_mapping) # 仅对字符串列填充空字符串 df['user_name'] = df['user_name'].fillna("") df.to_sql(table_name, con=engine, if_exists='append', index=False)
3. 定位具体出错的列/行
若仍报错,可临时关闭fast_executemany(注释掉监听事件),或添加异常捕获打印当前数据,定位问题列:
try: df.to_sql(table_name, con=engine, if_exists='append', index=False) except Exception as e: print("出错数据预览:") print(df.head()) raise e
4. 核对SQL Server表结构
确认表中各列的数据类型:比如INT类型列无法接受空字符串,VARCHAR类型列则允许空字符串。
内容的提问来源于stack exchange,提问作者user
相关产品推荐
相关产品推荐

