2016-09-09 8 views
1

バルクは、私はユーバーのにVertica-pythonのパッケージを使用して、Pythonの使用にVerticaにCSVファイルからデータをインポートしようとしている

の質問1をユーバーのにVertica-pythonのパッケージを使ってPythonを使用してのVerticaに挿入します。問題は、空白のみのデータ要素がVerticaにNULLとしてロードされていることです。空のデータ要素だけをNULLとして読み込み、空ではない空白データ要素を空白として読み込むようにします。

たとえば、次の2行のCSVファイルは、( '1'、 'abc'、NULL、NULL)として読み込まれますが、 、 'abc'、 ''、NULL)。ここで

1,abc,,^M 
1,abc, ,^M 

はコードです:

# import vertica-python package by Uber 
# source: https://github.com/uber/vertica-python 
import vertica_python 

# write CSV file 
filename = 'temp.csv' 
data = <list of lists, e.g. [[1,'abc',None,'def'],[2,'b','c','d']]> 
with open(filename, 'w', newline='', encoding='utf-8') as f: 
     writer = csv.writer(f, escapechar='\\', doublequote=False) 
     writer.writerows(data) 

# define query 
q = "copy <table_name> (<column_names>) from stdin "\ 
    "delimiter ',' "\ 
    "enclosed by '\"' "\ 
    "record terminator E'\\r' " 

# copy data 
conn = vertica_python.connect(host=<host>, 
           port=<port>, 
           user=<user>, 
           password=<password>, 
           database=<database>, 
           charset='utf8') 
cur = conn.cursor() 
with open(filename, 'rb') as f: 
    cur.copy(q, f) 
conn.close() 

質問2 2

の私はロードのこの方法を使用するために注意する必要があり、他の問題(例えば文字エンコーディング)がありますデータをVerticaに入力しますか?コードに間違いがありますか?私は100%がすべてのプラットフォーム(現在Linux上で動作している;他のプラットフォームではターミネータの問題が記録されているなど)で動作すると確信しているわけではありません。このコードをより堅牢にするための推奨事項は、非常に高く評価されます。

さらに、速度を犠牲にすることなく、最初にCSVファイルに書き込むのではなく、Pythonから直接オブジェクトを読み込むなど、Pythonからデータを一括してVerticaに挿入する方法がありますか?データ量は大きく、挿入ジョブの実行には数時間かかります。

ご協力いただきありがとうございます。

答えて

1

あなたが持っているコピーステートメントは、スペースに関して必要な方法で実行する必要があります。私はそれに非常によく似たCOPYを使ってテストしました。

編集:

空白を修正するには、あなたがあなたのコピー文を変更することができます。私はあなたが本当にコピーを求めていたものを逃した、私はそれはまだいくつかの人々のために有用である可能性があるためにこの部分を残しておきます:

copy <table_name> (FIELD1, FIELD2, MYFIELD3 AS FILLER VARCHAR(50), FIELD4, FIELD3 AS NVL(MYFIELD3,'')) from stdin 

フィラーを使用することにより、それはあなたが、後でコピーで ASを使用して、実際のテーブルのフィールドに割り当てることができる変数のようなものの中にそれを解析します。

私はあなたがSolarisによくあることをしています。私が気づいた唯一の事は、レコードターミネータを設定していることです。環境に依存する必要があるかどうかはわかりません。私はそれをLinux、Windows、およびSolarisの間で切り替える必要はなかった。

また、ヒントは、ロードされた行の数を示す結果セットを返します。 fetchone()を実行して印刷してください。

私がお勧めできるのは、行が拒否された場合に拒否テーブルを使用することだけです。

あなたは大きな仕事だと言いました。接続に'read_timeout': 7200,以上を追加して、読み取りタイムアウトを増やす必要があります。 Noneが読み取りタイムアウトを無効にするかどうかはわかりません。

より速い方法として、ファイルがバーチカノード自体で直接アクセスできる場合は、copy from stdinを実行する代わりにファイルを直接参照し、デーモンに直接ロードさせることができます。これははるかに高速で、いくつかの最適化が可能です。次に、割り当てられた負荷を使用することができます。複数のファイルをロードする場合は、それらのファイルをすべてファイルのリストで参照するだけで済みます。

これは長い話題ですが、特定の質問がある場合は、私に知らせてください。

+0

ありがとうございました!あなたの提案が3列目のNULLを ''で置き換えるのではないでしょうか?私は、次のようにデータをロードしようとしています:要素が空の場合、それをNULLとしてVerticaにロードします。要素が長さ> 0の空白文字列であれば、それをそのままVerticaにロードします。私は誤読ですか?質問の元の言葉がこの時点ではっきりしていなかったことを謝ります。 – verbatross

+0

他のもの:これらの素晴らしい提案に感謝します!私の場合、レコードターミネータが必要です(Ubuntu)。いくつかのデータ要素に改行文字があります。行が拒否された場合の表を却下することは素晴らしい考えです。デーモンによる読み込みも素晴らしい。それが可能であることを認識していない。 – verbatross

+0

申し訳ありませんが私は誤解しました。私はそれを行う方法について考えているが、私は今それをテストすることはできない。私はそれに戻ります。そして私はそれがまさしく私のビジネスのどれかではないことを知っていますが、私はそのようなフィールドにスペースを格納するという考えは本当に好きではありません。一般的には良いことではありません。 – woot

関連する問題