Python 将bytearray从VARBINARY(16)列转换为IP地址

Python 将bytearray从VARBINARY(16)列转换为IP地址,python,arrays,byte,pyodbc,vertica,Python,Arrays,Byte,Pyodbc,Vertica,我需要从HP Vertica数据库中提取大量数据并将其保存到文件中。我正在使用Vertica的官方ODBC驱动程序和pyodbc 这就是我到目前为止所做的: cnxn = pyodbc.connect('DRIVER={Vertica};SERVER=localhost;DATABASE=db;UID=user;PWD=pw') cnxn.setdecoding(pyodbc.SQL_CHAR, encoding='utf-8') cnxn.setdecoding(pyodbc.SQL_WCHA

我需要从HP Vertica数据库中提取大量数据并将其保存到文件中。我正在使用Vertica的官方ODBC驱动程序和pyodbc

这就是我到目前为止所做的:

cnxn = pyodbc.connect('DRIVER={Vertica};SERVER=localhost;DATABASE=db;UID=user;PWD=pw')
cnxn.setdecoding(pyodbc.SQL_CHAR, encoding='utf-8')
cnxn.setdecoding(pyodbc.SQL_WCHAR, encoding='utf-8')
cnxn.setencoding(str, encoding='utf-8')
cnxn.setencoding(unicode, encoding='utf-8')
cur = cnxn.cursor()
cur.execute("SELECT * FROM schema.table LIMIT 3")
然后我读了数据

for row in cur:
    print row
大多数字段都返回得很好-unicode文本、数字或日期时间。但是,对于存储IP地址的字段,我得到以下信息:

bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\no\x19\\')
如何将其转换为文本

非常感谢您对我们的任何帮助

谢谢

VARBINARY(16)是128位,这正是IPv6地址的正确大小。样本数据解码为

0000:0000:0000:0000:0000:ffff:0a6f:195c
维基百科关于IPv6的文章(参考:)中的“IPv4映射的IPv6地址”小节说,这样的地址是映射到IPv6格式(128位)的IPv4地址(32位)

::ffff:10.111.25.92
我们可以使用如下函数从原始
bytearray
数据生成上述字符串表示:

def字节到ip地址(字节数组):
如果字节数组[0:12]==bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff'):
返回'{0}.{1}.{2}.{3}'。格式(字节数组[12],字节数组[13],字节数组[14],字节数组[15])
其他:
返回“:”.join([{0:02x}{1:02x}.format(byte_数组[i],byte_数组[i+1]),用于范围(0,len(byte_数组),2)]中的i)
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
#例子
fld=bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\no\x19\\\')
打印(字节到ip地址(fld))#10.111.25.92
fld=字节数组(b'\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\no\x19\\\')
打印(字节到ip地址(fld))0100:0000:0000:0000:0000:ffff:0a6f:195c
或者,通过Python3,我们可以使用以下模块:

导入IP地址
def字节到ip地址(字节数组):
ip6=ipaddress.IPV6地址(字节(字节数组))
ip4=ip6.ipv4\u映射
如果ip4==无:
返回str(ip6)
其他:
返回str(ip4)
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
#例子
fld=bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\no\x19\\\')
打印(字节到ip地址(fld))#10.111.25.92
fld=字节数组(b'\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\no\x19\\\')
打印(字节到ip地址(fld))#100::ffff:a6f:195c

我知道有一个公认的答案,但。。。对于所有其他人:

如果您的数据在Vertica中,那么要做的第一件事就是查看fine SQL参考手册。在本例中,您将找到一个内置函数,用于将表示为VARBINARY列的IPv6地址转换为字符串

更简单、更快捷:

SELECT V6_NTOA(your_column_here) ;

表定义中对应的列类型是什么?您知道这些字节应该表示的IP地址吗?@GordThompson表定义中对应的列类型是varbinary(16)。我不知道这些字节对应于哪个IP地址。用我目前的设置来检查并不容易。