2011-01-04 5 views
2

私は数十億行のデータをCSVファイルに保存しています。各行には10〜20個の列があります。 COPY FROMを使用して、20列の表にデータをロードします。特定のCSV行に10列のデータしか含まれていない場合は、COPY FROMが残りの列(値が欠落している)をNULLに設定すると予想されます。 CREATE TABLEステートメントのすべての列にDEFAULT NULLを指定します。Postgresql:occasion missingカラムを含むcsvファイルからのコピー

ご質問: これはCOPY FROMを使用して行うことができますか?

EDIT:Greenplum(PostgreSQLベースのデータベース)にはFILL MISSING FIELDSという名前のスイッチがあり、これは私が記述したものです(ドキュメントhereを参照)。 PostgreSQLにはどのような回避策をお勧めしますか? PostgreSQL manualから

答えて

2

と同様のことを行う:

その後、次の行を分割し、列を抽出し、このような何かするためにSQLを使用することができます十分な列を持たない行に余分なカンマを追加するか、CSVをTSV(タブ区切り)に変換して余分な列に "\ N"を入れるだけです。

0

COPY入力ファイルのいずれかの ラインが予想されるよりも より多くのまたはより少ない列が含まれている場合は、エラーが発生しますFROM。

COPY文で名前を付ける必要のある列の数を確認するには、CSVファイルの最初の行を参照してください。

+0

どのような回避策をお勧めしますか? – David

+1

ファイルを前処理するスクリプトを作成します。たとえば、区切り文字の数が不足していることを確認してください。あなたがscritpsを書くのが好きなら –

1

私は、COPY FROMが同じファイル内の異なる数の列を扱うとは思わないと思います。

常に同じ10個の列がない場合は、すべてを最初にtext列のステージングテーブルにロードすることが考えられます。に前処理スクリプトを書く

 
INSERT INTO target_table (col1, col2, col3, col4, col5, ...) 
SELECT columns[1], columns[2], ... 
FROM ( 
    SELECT string_to_array(big_column, ',') as columns 
    FROM staging_table 
) t 
WHERE array_length(columns) = 10 

、その後array_length(columns) = 20

+0

これはこれを行う方法のようですが、すべてのデータを2つのテーブルに挿入する必要があるため、パフォーマンスが心配です。 – David

+0

CSVファイルの作成プロセスを変更できない限り、別の方法はありません –

1

文脈でetldata-warehouse - 私の提案は実際にあなたが探している "ショートカット"を避けることです。

ETLは、ECCD(抽出、クリーン、コンフォーム、デリバー)として頻繁に実装されるプロセスです。これらのファイルを「抽出済み」として扱うことができます。そのため、単純にデータの消去と実装を異なる手順として実装することができます。そのためには余分なディスク容量が必要です。すべての準拠したファイルは、 "最終"(すべての列)構造を持つ必要があります。その後、適合したファイルを配信します(COPY FROM)。

このようにして、ETLプロセスを文書化し、各ステップの欠落したフィールドに何が起こるかを記録することもできます。

監査およびデバッグの目的でオリジナルの顧客ファイルと適合バージョンを(ディスク、DVD)にアーカイブするのが普通の方法です。

+0

ありがとうございます。私は実際にはもう少し先に進む必要があると感じていましたが、これを読んだら、それはどうにかして行く正しい方法と思われます:) – Smalcat

関連する問題