pyodbc 解包 SQL_GUID 以转换为小写字符串
pyodbc unpacking SQL_GUID for converting to lowercase string
sql-server 和 pyodbc return 所有 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 服务器 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)
它returns
'f573a57d-9247-44cb-936a-d16dd4e8327f'
sql-server 和 pyodbc return 所有 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 服务器 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)
它returns
'f573a57d-9247-44cb-936a-d16dd4e8327f'