sql-server和pyodbc以大写形式返回所有SQL_GUID数据类型,而查询不区分大小写:

psql.py --sql="select controllerid from controllers where controllerid='F573A57D-9247-44CB-936A-D16DD4E8327F'"
[('F573A57D-9247-44CB-936A-D16DD4E8327F', )]
psql.py --sql="select controllerid from controllers where controllerid='f573a57d-9247-44cb-936a-d16dd4e8327f'"
[('F573A57D-9247-44CB-936A-D16DD4E8327F', )]


我希望它以小写形式输出。
添加了pyodbc.add_output_converter()方法,该方法对SQL_GUID的作用较小,但这是一个打包的结构:

def guid_to_lowercase(value):
    return value.lower()

pyodbc.add_output_converter(pyodbc.SQL_GUID, guid_to_lowercase)

[(b'}\xa5s\xf5g\x92\xcbd\x93j\xd1m\xd4\xe82\x7f', )]


它看起来像一个字节,但是更改了它:

def guid_to_lowercase(value):
    #log.error("type:{}".format(type(value)))
    return value.decode("ascii").lower()

UnicodeDecodeError: 'ascii' codec can't decode byte 0xa5 in position 1: ordinal not in range(128)

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xa5 in position 1: invalid start byte


我认为我需要打开包装,但格式如何。

在pyodbc之外,我可以执行uuid.lower()

最佳答案

当我们打印出服务器为GUID返回的原始字节时

'F573A57D-9247-44CB-936A-D16DD4E8327F'


我们得到

b'}\xa5s\xf5g\x92\xcbd\x93j\xd1m\xd4\xe82\x7f'


将ASCII字符转换为其十六进制值,删除\x前缀,并添加一些空格

7da573f5 4792 cb44 936a d16dd4e8327f


揭示了SQL Server ODBC正在返回GUID的字节,但是前三个段是按照小端顺序排列的,而后两个段是按照大端顺序排列的。

因此,如果我们将输出转换器功能更改为

def guid_to_lowercase(value):
    first_three_values = struct.unpack('<I2H', value[:8])
    fourth_value = struct.unpack('>H', value[8:10])[0]
    fifth_value = struct.unpack('>Q', b'\x00\x00' + value[10:16])[0]
    guid_string_parts = (
        '{:08x}'.format(first_three_values[0]),
        '{:04x}'.format(first_three_values[1]),
        '{:04x}'.format(first_three_values[2]),
        '{:04x}'.format(fourth_value),
        '{:012x}'.format(fifth_value),
    )
    return '-'.join(guid_string_parts)


它返回

'f573a57d-9247-44cb-936a-d16dd4e8327f'

关于python - pyodbc解压SQL_GUID转换为小写字符串,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50371691/

10-16 12:25