ODBC SQL类型-155尚不支持
问题描述:
我按照此link来查询Azure数据库。ODBC SQL类型-155尚不支持
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的新手。任何人都可以帮忙
答
pyodbc支持Output Converter functions当数据库返回pyodbc本身不支持SQL类型,我们可以使用。上面链接维基页的示例将执行类似于将由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
答
ODBC SQL类型-155对应于SQL Server类型DatetimeOFFSET
和ODBC类型。在这个documentation page中描述了ODBC类型和SQL Server类型之间的映射。该错误消息表示,此SQL Server数据类型当前不受Python ODBC API支持。
要解决此问题,您需要更改查询以避免查询使用DatetimeOFFSET
数据类型的列。一种方法是确定FinancialRecord
表中具有DatetimeOFFSET
数据类型的列,并将它们转换为nvarchar(100)
类型。
SELECT CAST(MyColumn as AS nvarchar(100)) AS MyColumnAsNVarChar', ...
FROM FinancialRecord where deleted=0