2017-09-28 17 views
2

HP Verticaデータベースから大量のデータを抽出してファイルに保存する必要があります。私はpyodbcでVerticaの公式ODBCドライバを使用しています。bytearrayをVARBINARY(16)列からIPアドレスに変換する

これは私がこれまでにやっていることです:

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\\') 

テキストに変換するにはどうすればよいですか?

大変お手伝いをしてください。

ありがとうございます!

+0

テーブル定義内の対応する列の型は何ですか?それらのバイトが表すはずのIPアドレスを知っていますか? –

+0

@GordThompsonテーブル定義の対応する列の型はvarbinary(16)です。私はそれらのバイトが対応するIPアドレスを知らない。現在の設定で確認するのは簡単ではありません。 –

答えて

3

私には受け入れられた答えがありますが、他のすべての人には:

データがVerticaにある場合は、非常にとしてください。詳細は、SQLリファレンス・マニュアルを参照してください。この場合、VARBINARY列として表されるIPv6アドレスを文字列に変換する組み込み関数があります。

はるかに単純とは、はるかに高速:

SELECT V6_NTOA(your_column_here) ; 
1

VARBINARY(16)は128ビットで、これはIPv6アドレスに適したサイズです。サンプルデータは

0000:0000:0000:0000:0000:ffff:0a6f:195c 

にデコードし、IPv6をWikipediaの記事のサブセクションを「IPv4マップIPv6アドレス」(REF:here)は、そのようなアドレスは、IPv6にマッピングされたIPv4アドレス(32ビット)であることを言いますフォーマット(128ビット)。

::ffff:10.111.25.92 
私たちは、このような機能を使って生 bytearrayデータから上記それらの文字列表現を生成することができます

import ipaddress 


def bytes_to_ip_address(byte_array): 
    ip6 = ipaddress.IPv6Address(bytes(byte_array)) 
    ip4 = ip6.ipv4_mapped 
    if ip4 == None: 
     return str(ip6) 
    else: 
     return str(ip4) 


if __name__ == '__main__': 
    # examples 
    fld = bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\no\x19\\') 
    print(bytes_to_ip_address(fld)) # 10.111.25.92 
    fld = bytearray(b'\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\no\x19\\') 
    print(bytes_to_ip_address(fld)) # 100::ffff:a6f:195c 
:我々は ipaddressモジュールを使用することができるのpython3で

def bytes_to_ip_address(byte_array): 
    if byte_array[0:12] == bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff'): 
     return '{0}.{1}.{2}.{3}'.format(byte_array[12], byte_array[13], byte_array[14], byte_array[15]) 
    else: 
     return ':'.join(['{0:02x}{1:02x}'.format(byte_array[i], byte_array[i + 1]) for i in range(0, len(byte_array), 2)]) 


if __name__ == '__main__': 
    # examples 
    fld = bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\no\x19\\') 
    print(bytes_to_ip_address(fld)) # 10.111.25.92 
    fld = bytearray(b'\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\no\x19\\') 
    print(bytes_to_ip_address(fld)) # 0100:0000:0000:0000:0000:ffff:0a6f:195c 

かを、

関連する問題