使用Python导入CSV到SQL时遇‘字符串过长’错误求助
问题
使用Python将数据导入SQL时,针对285字符长度的字符串持续触发「字符串过长」异常。已将GG表的TweetText列类型定义为varchar(max),且手动替换row.TweetText为该字符串后可正常导入,怀疑问题出在row.TweetText本身,求原因及解决办法。
涉及代码
import sys import pypyodbc as odbc import pandas as pd import os import csv def connect(path): data = pd.read_csv (path) data.rename( columns={'Unnamed: 0':'TweetNumber'}, inplace=True ) df = pd.DataFrame(data) SERVER_NAME = 'DESKTOP-9736NS2\SQLEXPRESS' DATABASE_NAME = 'DB.Tweets' DRIVER= 'SQL Server' conn_string = f""" Driver={{{DRIVER}}}; Server={{{SERVER_NAME}}}; Database={{{DATABASE_NAME}}}; Trust_Connection=yes; """ try: conn = odbc.connect(conn_string) except Exception as e: print(e) print('task is terminated') sys.exit() else: cursor = conn.cursor() insert_statement = """ INSERT INTO [GG] VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?); """ try: toggle =0 for row in df.itertuples(): cursor.execute(insert_statement,(row.TweetNumber, row.UserName, row.RealName, row.FollowerCount, row.TweetCount, row.TweetText, row.TweetLikes, row.TweetRetweets, row.TweetId, row.DatePosted, row.MediaUrl)) if toggle ==0: print(print(row.UserName)) toggle=1 except Exception as e: print(e) cursor.rollback() print('transaction rolled back') stop=1 else: print('records inserted succesfully') cursor.commit() cursor.close() stop=0 finally: if conn.connected == 1: print('connection closed') conn.close() return(stop) g=1 stop = 0 for filename in os.scandir('C:/Users/Christian/OneDrive - University of Copenhagen/Documents/UniKU/AProjects/DatabaseProject/TwitterTweetData'): if stop ==0: if g == 1: if filename.is_file(): connect(filename.path) stop=connect(filename.path)
SQL表字段类型
GG表的TweetText列已设置为varchar(max),其余字段类型匹配导入数据的常规类型(如数字类字段对应整数/浮点类型,日期字段对应日期类型等)。
原因分析
- CSV读取时的字符串异常:pandas读取CSV时,默认可能对长字符串做截断,或把带特殊字符的字符串识别为异常类型,导致
row.TweetText的实际内容要么不完整,要么包含不可见控制字符(比如换行、制表符),这些字符会增加实际字节数,触发SQL的长度校验。 - itertuples的类型转换问题:
df.itertuples()返回的是Pandas自定义对象,部分字符串在转换过程中可能出现类型偏差,导致传递给pypyodbc时的参数长度与实际字符串长度不符,驱动误判为过长。 - 参数顺序错位:如果INSERT语句的参数顺序和GG表的字段顺序不匹配,可能把TweetText的长字符串传入其他短长度字段,直接触发「字符串过长」错误。
解决方案
- 强制CSV读取的字符串类型:读取CSV时指定TweetText为字符串类型,避免自动截断或类型转换:
data = pd.read_csv(path, dtype={'TweetText': str})
- 清理特殊字符:对
row.TweetText做预处理,移除不可见控制字符:
# 在插入前清理文本 clean_tweet = row.TweetText.replace('\n', ' ').replace('\r', ' ').replace('\t', ' ').strip() # 执行插入时用clean_tweet替代row.TweetText cursor.execute(insert_statement,(row.TweetNumber, row.UserName, row.RealName, row.FollowerCount, row.TweetCount, clean_tweet, row.TweetLikes, row.TweetRetweets, row.TweetId, row.DatePosted, row.MediaUrl))
- 改用批量插入:放弃逐行插入,用pandas的
to_sql方法直接批量导入,自动适配SQL字段类型:
# 替换原有的逐行循环逻辑 data.to_sql('GG', conn, if_exists='append', index=False)
- 核对参数顺序:检查INSERT语句的
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)顺序,确保和GG表的字段顺序完全一致,避免错位导致的错误。
内容的提问来源于stack exchange,提问作者hhhhhhhh
相关产品推荐
相关产品推荐

