ODBC SQL 类型 -155 尚不支持

ODBC SQL type -155 is not yet supported

我按照这个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()

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

Traceback (most recent call last): File "sqltest.py", line 10, in row = cursor.fetchone() pyodbc.ProgrammingError: ('ODBC SQL type -155 is not yet supported. column-index=2 type=-155', 'HY106')

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

ODBC SQL类型-155对应SQL服务器类型DatetimeOFFSET和ODBC类型SQL_SS_TIMESTAMPOFFSET。 ODBC 类型和 SQL 服务器类型之间的映射在此 documentation page 中进行了描述。错误消息指出 SQL 服务器数据类型当前不受 Python ODBC API.

支持

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

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

pyodbc 支持 Output Converter functions,我们可以在数据库 returns 和 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