从 MS SQL Server 数据库创建 DataFrame 时出现 Pandas 错误:“尚不支持 ODBC SQL 类型 -151”

MCG*_*ode 3 python sql-server pandas

我正在尝试从 MS SQL Server 2016 中的表创建 DataFrame,我使用了示例数据库 AdventureWorks2012,代码如下:

import pyodbc 
cnxn = pyodbc.connect("Driver={ODBC Driver 13 for SQL Server};"
                      "Server=localhost;"
                      "Database=AdventureWorks2012;"
                      "Trusted_Connection=yes;")


cursor = cnxn.cursor()
cursor.execute('SELECT * FROM HumanResources.Employee')

df = pandas.read_sql(sql, cnxn)
cursor.close()
cnxn.close()
Run Code Online (Sandbox Code Playgroud)

但我收到一个错误:

----> 1 df = pandas.read_sql(sql, cnxn)

ProgrammingError: ('ODBC SQL type -151 is not not supported. column-index=3 type=-151', 'HY106')

Scr*_*urr 7

因此,我将创建我的答案,因为我现在知道您的问题的完整背景。该问题与新的 MS SQL Server 2016 的 ODBC 驱动程序兼容性问题有关。您提到您可以将字段缩减为数据类型为hierarchyid 的字段。根据此处提供的文档,您可以将其转换为nvarchar(4000)字符串表示形式。因此,您的解决方案将取决于您如何编写查询。

您当前的代码为:

cursor.execute('SELECT * FROM HumanResources.Employee')
Run Code Online (Sandbox Code Playgroud)

我将其修改为:

cursor.execute("""
SELECT CAST(theHierarchyIdField AS NVARCHAR(4000)) AS myConvertedField
    ,additionalField
    ,...
FROM HumanResources.Employee
""")
Run Code Online (Sandbox Code Playgroud)

我可以理解,在查询中显式写入要提取的所有字段会很烦人,但这是在将其作为可识别的数据类型提取到 Python 之前在 SQL 端进行转换的唯一方法。

另一种解决方案是重新设计您的表架构并将hierarchyid类型更改为nvarchar(4000),但我不知道您是否有权更改表,因此我将提出上述解决方案。

此外,如果您打算使用pandas拉入数据,那么只需将您的sql变量设置为查询字符串和read_sql

sql = """
SELECT CAST(theHierarchyIdField AS NVARCHAR(4000)) AS myConvertedField
    ,additionalField
    ,...
FROM HumanResources.Employee
"""

df = pandas.read_sql(sql, cnxn)
Run Code Online (Sandbox Code Playgroud)


adr*_*ien 7

如果您不使用 ODBC 类型 -151 (TSQL hierarchid ) 的列,您可以简单地在连接上添加一个数据类型处理程序,将其转换为字符串:

    def HandleHierarchyId(v):
      return str(v)

    conn = pyodbc.connect(connection_string)
    conn.add_output_converter(-151, HandleHierarchyId)
Run Code Online (Sandbox Code Playgroud)

您还可以使用此处列出的任何其他方法来转换此类型。