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

使用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的长字符串传入其他短长度字段,直接触发「字符串过长」错误。

解决方案

  1. 强制CSV读取的字符串类型:读取CSV时指定TweetText为字符串类型,避免自动截断或类型转换:
data = pd.read_csv(path, dtype={'TweetText': str})
  1. 清理特殊字符:对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))
  1. 改用批量插入:放弃逐行插入,用pandas的to_sql方法直接批量导入,自动适配SQL字段类型:
# 替换原有的逐行循环逻辑
data.to_sql('GG', conn, if_exists='append', index=False)
  1. 核对参数顺序:检查INSERT语句的VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)顺序,确保和GG表的字段顺序完全一致,避免错位导致的错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 04:10:13