ODBC SQL类型-155尚不支持

时间:2017-09-25 12:32:37

标签: python sql-server azure-sql-database pyodbc

我按照此link来查询Azure数据库。

import pyodbc
server = 'your_server.database.windows.net'
database = 'your_database'
username = 'your_username'
password = 'your_password'
driver= '{ODBC Driver 13 for SQL Server}'
cnxn = pyodbc.connect('DRIVER='+driver+';PORT=1433;SERVER='+server+';PORT=1443;DATABASE='+database+';UID='+username+';PWD='+ password)
cursor = cnxn.cursor()
cursor.execute("SELECT * FROM FinancialRecord where deleted=0")
row = cursor.fetchone()
while row:
    print (str(row[0]) + " " + str(row[1]))
    row = cursor.fetchone()

当我运行上面的代码时,它会显示错误。

  

追踪(最近一次通话):     文件" sqltest.py",第10行,in       row = cursor.fetchone()   pyodbc.ProgrammingError :(' ODBC SQL类型-155尚不支持.column-index = 2 type = -155',' HY106')

我是Azure新手。有人可以帮忙吗?

2 个答案:

答案 0 :(得分:6)

pyodbc支持Output Converter functions,当数据库返回pyodbc本身不支持的SQL类型时,我们可以使用它。上面链接的Wiki页面上的示例将执行类似于服务器上的CAST到[N] VARCHAR所实现的客户端转换:

import struct
import pyodbc
conn = pyodbc.connect("DSN=myDb")


def handle_datetimeoffset(dto_value):
    # ref: https://github.com/mkleehammer/pyodbc/issues/134#issuecomment-281739794
    tup = struct.unpack("<6hI2h", dto_value)  # e.g., (2017, 3, 16, 10, 35, 18, 0, -6, 0)
    tweaked = [tup[i] // 100 if i == 6 else tup[i] for i in range(len(tup))]
    return "{:04d}-{:02d}-{:02d} {:02d}:{:02d}:{:02d}.{:07d} {:+03d}:{:02d}".format(*tweaked)


crsr = conn.cursor()
# create test data
crsr.execute("CREATE TABLE #dto_test (id INT PRIMARY KEY, dto_col DATETIMEOFFSET)")
crsr.execute("INSERT INTO #dto_test (id, dto_col) VALUES (1, '2017-03-16 10:35:18 -06:00')")

conn.add_output_converter(-155, handle_datetimeoffset)
value = crsr.execute("SELECT dto_col FROM #dto_test WHERE id=1").fetchval()
print(value)

crsr.close()
conn.close()

打印

2017-03-16 10:35:18.0000000 -06:00

答案 1 :(得分:2)

ODBC SQL类型-155对应于SQL Server类型DatetimeOFFSET和ODBC类型SQL_SS_TIMESTAMPOFFSET。 ODBC类型和SQL Server类型之间的映射在此documentation page中描述。该错误消息表明Python ODBC API当前不支持此SQL Server数据类型。

要解决此问题,您需要更改查询以避免查询具有DatetimeOFFSET数据类型的列。一种方法是确定FinancialRecord表中具有DatetimeOFFSET数据类型的列,并将其转换为nvarchar(100)类型。

SELECT CAST(MyColumn as AS nvarchar(100)) AS MyColumnAsNVarChar', ...
FROM FinancialRecord where deleted=0