我尝试从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()
但是我收到了错误:
----> 1 df = pandas.read_sql(sql,cnxn)
ProgrammingError :(' ODBC SQL类型-151尚不支持.column-index = 3 type = -151',' HY106')
答案 0 :(得分:1)
所以我只是创建我的答案,因为我现在知道你的问题的完整背景。此问题与新的MS SQL Server 2016的ODBC驱动程序兼容性问题有关。您提到您可以将字段缩小为数据类型为 hierarchyid 的字段。根据提供的文档here,您可以将其转换为nvarchar(4000)
字符串表示形式。因此,您的解决方案将是您编写查询的方式。
您的代码目前为:
cursor.execute('SELECT * FROM HumanResources.Employee')
我会将其修改为:
cursor.execute("""
SELECT CAST(theHierarchyIdField AS NVARCHAR(4000)) AS myConvertedField
,additionalField
,...
FROM HumanResources.Employee
""")
我可以理解,显式编写查询中要提取的所有字段会很烦人,但它是在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)
答案 1 :(得分:1)
如果您不使用ODBC类型为-151(TSQL hierarchid)的列,则只需在连接上添加一个数据类型处理程序即可将其转换为字符串:
def HandleHierarchyId(v):
return str(v)
conn = pyodbc.connect(connection_string)
conn.add_output_converter(-151, HandleHierarchyId)
您还可以使用here中列出的任何其他方法来转换此类型。
答案 2 :(得分:0)
来自documentation ... for
pandas.read_sql(sql, con,
index_col=None, coerce_float=True, params=None,
parse_dates=None, columns=None, chunksize=None)
sql : string SQL query or SQLAlchemy Selectable (select or text object)
to be executed, or database table name.
换句话说,参数应该是SQL查询或其他一些机制来选择你想要的行和列。
在您的代码中,您没有将变量sql
定义为查询,但您在此行中使用它:
df = pandas.read_sql(sql, cnxn)
我的建议是pandas
混淆并提供您描述的错误。
试试这个,看看你是否更接近目标:
sql = cursor.execute('SELECT * FROM HumanResources.Employee')
df = pandas.read_sql(sql, cnxn)