【问题标题】:pyodbc.DataError: ('22018', '[22018] [Microsoft][ODBC Driver 17 for SQL Server]Invalid character value for cast specification (0) (SQLExecute)')pyodbc.DataError: (\'22018\', \'[22018] [Microsoft][ODBC Driver 17 for SQL Server]强制转换规范 (0) (SQLExecute)\'的字符值无效)
【发布时间】:2022-10-19 03:00:14
【问题描述】:

我遇到了 pyodbc dataError -

尝试读取 csv 文件(使用 Pandas 库)后,使用 dataframe.to_sql() 插入 db 表。我的数据框中的所有空值都是无。

顺便说一句,我在处理一个文件时遇到了这个错误。该程序成功执行了另外两个文件(包含大约 500K 行)......此外,成功将数据插入到 db 表中的文件在数据框中的 None 类型中设置了 NULL。

fast_executemany = False 应该可以工作,并且确实如here 所述工作。我已经尝试过了,我没有遇到错误。但是,问题是我正在处理的文件(包含至少 200K 行)非常缓慢。

环境:Windows 10 Python 3.9.6 pyodbc 4.0.32

你能告诉我是否有不同的方法吗?

下面的代码:

import sqlalchemy as sq, pyodbc as po, os, pandas as pd,

conn = sq.create_engine(f'mssql+pyodbc://dbname/tablename?trusted_connection=yes&driver=ODBC Driver 17 for SQL Server',fast_executemany = True)
#print(conn)

os.chdir(r"some path")

col_types = {
    'col 1':sq.types.INTEGER(),
    'col 2':sq.types.VARCHAR(length=100),
    'col 3':sq.types.INTEGER(),
    'col 4':sq.types.VARCHAR(length=100),
    'col 5':sq.types.DateTime(),
    'col 6':sq.types.VARCHAR(length=5),
    'col 7':sq.types.DateTime(),
    'col 8':sq.types.VARCHAR(length=5),
    'col 9':sq.types.DateTime(),
    'col 10':sq.types.VARCHAR(length=5),
    'col 11':sq.types.DateTime(),
    'col 12':sq.types.VARCHAR(length=5),
    'col 13':sq.types.Float(),
    'col 14':sq.types.Float(),
    'col 15':sq.types.Float(),
    'col 16':sq.types.INTEGER(),
    'col 17':sq.types.VARCHAR(length=1000),
    'col 18':sq.types.VARCHAR(length=100),
    'col 19':sq.types.VARCHAR(length=1000),
    'col 20':sq.types.DateTime(),
    'col 21':sq.types.VARCHAR(length=5),
    'col 22':sq.types.DateTime(),
    'col 23':sq.types.VARCHAR(length=5),
    'col 24':sq.types.VARCHAR(length=50),
    'col 25':sq.types.VARCHAR(length=50),
    'col 26':sq.types.Float(),
    'col 27':sq.types.Float(),
    'col 28':sq.types.Float(),
    'col 29':sq.types.VARCHAR(length=150),
    'col 30':sq.types.VARCHAR(length=1000),
    'col 31':sq.types.VARCHAR(length=1000),
    'col 32':sq.types.VARCHAR(length=100),
    'col 33':sq.types.VARCHAR(length=100),
    'col 34':sq.types.INTEGER(),
    'col 35':sq.types.VARCHAR(length=100),
    'col 36':sq.types.Float(),
    'col 37':sq.types.Float(),
    'col 38':sq.types.VARCHAR(length=10),
    'col 39':sq.types.Float(),
    'col 40':sq.types.VARCHAR(length=1000),
    'col 41':sq.types.VARCHAR(length=20)
};

for f in os.listdir():
    if f.endswith(".txt"):
        df = pd.read_csv(f, sep='\t', low_memory=False)
        df.to_sql(tablename, con = conn, if_exists = 'append', index=False, dtype=col_types)

【问题讨论】:

  • 我强烈怀疑您实际上在 DataFrame 中有一个或多个空字符串,而您没有意识到这一点。
  • 我用 None 替换了所有 NaN 值并检查它是否可以工作。它没有:(
  • NaN 值不是问题;空字符串是。
  • 我将文件的前 10 行读入数据框中。尝试将其加载到表中。它因有问题的错误而失败。我检查了这 10 行中是否有任何空字符串。我什至一个都找不到。 res = df[df['col_name'] == ''].index //返回索引的空数组是的,我对所有日期时间列都试过了
  • 终于有突破了!昨天晚上,我列出的众多潜在解决方案之一是下面的一个。将数据框中的所有日期时间字符串转换为日期时间对象 df['column_name'] = pd.to_datetime(df['column_name'])作品!!我记得在某处(可能在 github 上)读到,您认为将这些日期时间字符串转换为 python 的“日期时间对象”实际上可以防止在 fast_executemany=True 的情况下发生此错误。我相信您已经通过在 python 中演示 datetime.isoformat() 来说明您的情况。这有帮助:)谢谢:)

标签: sql-server python-3.x pandas pyodbc executemany


【解决方案1】:

这行得通!


终于有突破了!昨天晚上,我列出的众多潜在解决方案之一是下面的一个。将日期帧中的所有日期时间字符串转换为日期时间对象 df['column_name'] = pd.to_datetime(df['column_name']) 有效!我记得在某处(可能在 github 上)读到,您认为将这些日期时间字符串转换为 python 的“日期时间对象”实际上可以防止在 fast_executemany=True 的情况下发生此错误。我相信您已经通过在 python 中演示 datetime.isoformat() 来说明您的情况。这有帮助:)谢谢:)

【讨论】:

    猜你喜欢
    • 2016-09-21
    • 1970-01-01
    • 2020-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多