【问题标题】:ODBC SQL type -155 is not yet supported尚不支持 ODBC SQL 类型 -155
【发布时间】:2017-09-25 12:32:37
【问题描述】:

我按照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(最近一次调用最后一次): 文件“sqltest.py”,第 10 行,在 行 = cursor.fetchone() pyodbc.ProgrammingError: ('ODBC SQL type -155 is not yet supported. column-index=2 type=-155', 'HY106')

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

【问题讨论】:

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


    【解决方案1】:

    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
    

    【讨论】:

    • 稍微简洁一点:year, month, day, hour, minute, second, nanoseconds, offset_hours, offset_minutes = struct.unpack("&lt;6hI2h", value) dt = datetime(year, month, day, hour, minute, second, nanoseconds // 1000, tzinfo=timezone(timedelta(hours=offset_hours, minutes=offset_minutes)))
    【解决方案2】:

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

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

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

    【讨论】:

    • 是的,它有效。对于时间和大小的优化,我只需要我需要的字符。以我为例:我只需要日期,而不是时间,然后我取“nvarchar(10)”
    猜你喜欢
    • 1970-01-01
    • 2014-07-23
    • 2011-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-02
    • 2011-12-31
    相关资源
    最近更新 更多