4

尝试将 executemanycolumns 与 SQL Server 一起使用时,我收到此错误:“无法将 Python 实例转换为 C++ 类型(在调试模式下编译以获取详细信息)”

我知道 Turbodbc 不喜欢 numpy 空值(NaN 或 NaT),所以要删除这些我使用:

df= df.where((pd.notnull(df)), 无)

然而,在运行这个之后,我得到一个错误,说一列不连续。这些总是 int64 数据类型的列。为了解决这个问题,我使用 arr.flags['C_CONTIGUOUS'] 检查每个数组,如果 False 则使用 np.ascontiguousarray(arr)。然后我再次收到“无法将 Python 实例转换为 C++ 类型(在调试模式下编译以获取详细信息)”错误。

我的数据框不包含 NaN 或 NaT。关于导致此错误的原因有什么想法吗?谢谢你的帮助!

4

3 回答 3

1

所以这个答案绝对不是对为什么会发生这个错误的完整解释,而是基于我自己在解决这个问题时发现的。

首先我需要参考这篇很棒的文章,它给了我构建导出到 SQL 的功能https://medium.com/@erickfis/etl-process-with-turbodbc-1d19ed71510e

在本文的末尾有一些回复和问题,其中一些与您的问题有关。其中有一个响应,说他们将数据帧写入 csv,然后读取该 csv,然后运行 ​​Turbodbc 代码。

我不确定为什么这可能会消除您看到的错误 - 并且为了避免违反答案的 SO 规则,我不会放下我对正在发生的事情的猜测,因为它可能没有帮助!

我决定遵循这个建议,因为我不知所措,谢天谢地,它工作并在大约 17 秒内导出了我的整个数据帧(20975 行和 100 列)!!!

我在使用 Turbodbc 时看到其他错误时所做的其他一些事情如下(可能与此特定问题没有直接关系,但可能有助于您进一步了解其他问题):

  - update numpy to most recent version
  - install dlib from whl file here https://pypi.org/simple/dlib/
  - install CMake using pip install 

我希望这会有所帮助,并且其他人可以为您提供更全面的解释!

于 2019-09-27T12:41:53.707 回答
1

我是作者

https://medium.com/@erickfis/etl-process-with-turbodbc-1d19ed71510e

好吧,根据我的经验,问题总是以下之一:

  • 缺失值
  • 错误的列名(编码、空格或禁止的名称)
  • 错误的字符串编码
  • 错误的日期编码

我昨天尝试用 MySQL 运行我的例程,但我收到错误“无法将 Python 实例转换为 C++ 类型”。

我做了什么来解决它:

  • 修复(规范化 - utf8 编码)列名
  • 为我的 df 中的每个 dtype 运行 fillna
  • 规范化文本(utf8 编码)
  • 提取列值
  • 再次运行我的 turbodbc 例程
  • 瞧,它有效

昨天我在清理日期之前提取了列值,因此我收到了错误。

因此,在仔细清理和准备数据之后,对于每个 dtype,您应该可以:

values = [df[col].values for col in df.columns]

colunas = '('
colunas += ', '.join(df.columns)
colunas += ')'

val_place_holder = ['?' for col in df.columns]
sql_val = '('
sql_val += ', '.join(val_place_holder)
sql_val += ')'

sql = f"""
INSERT INTO {mydb}.{table} {colunas}
VALUES {sql_val}
"""


with turbo_connection.cursor() as cursor:
    try:
        cursor.executemanycolumns(sql, values)
        turbo_connection.commit()
    except Exception as e:
        turbo_connection.rollback()
        raise(e)
于 2019-11-25T11:55:16.977 回答
0

首先,感谢 erickfis 在medium上的帖子!

阅读 turbodbc 文档后,我通过使用 numpy 的 MaskedArrays 将他的 df_valores 逻辑更改为:

import numpy as np
import pandas as pd
valores_df = [np.ma.MaskedArray(df[col].values, pd.isnull(df[col].values)) for col in df.columns]

这样,每个 df.col 中的 NaN 在期间正确转换为 sql NULL

cursor.executemanycolumns(sql, valores_df)

对我来说,这个小改动解决了我遇到的错误:

  • 无法将 Python 实例转换为 C++ 类型” 
  • ODBC 错误状态:42000 本机错误代码:8023 消息:[Microsoft][ODBC SQL Server Driver][SQL Server]传入的表格数据流 (TDS) 远程过程调用 (RPC) 协议流不正确。参数 34 (""):提供的值不是浮点数据类型的有效实例。
于 2020-04-24T10:32:32.670 回答