web-dev-qa-db-ja.com

CSVファイルのいくつかの列をテーブルにコピーします

10列のCSVファイルがあります。 4列のPostgreSQLテーブルを作成した後、10列の一部をテーブルにコピーします。

cSVテーブルの列は次のようなものです。

x1 x2 x3 x4 x5 x6 x7 x8 x9 x10

postgreSQLテーブルの列は次のようになります。

x2 x5 x7 x10
47
POTENZA

アドホックタスクの場合

入力ファイルのすべての列を含む一時テーブルを作成します

create temporary table t (x1 integer, ... , x10 text)

ファイルからコピーします:

copy t (x1, ... , x10)
from '/path/to/my_file'
with (format csv)

次に、tempから決定的なテーブルに挿入します。

insert into my_table (x2, x5, x7, x10)
select x2, x5, x7, x10
from t

それをドロップします:

drop table t

頻繁なタスクの場合

使用 - file_fdw拡張子 。スーパーユーザーとして:

create extension file_fdw;

create server my_csv foreign data wrapper file_fdw;

create foreign table my_csv (
    x1 integer,
    x2 text,
    x3 text
) server my_csv
options (filename '/tmp/my_csv.csv', format 'csv' )
;

テーブルの選択権限を、それを読み取るユーザーに付与します。

grant select on table my_csv to the_read_user;

その後、必要に応じてcsvファイルからテーブルであるかのように直接読み取ります。

insert into my_table (x2)
select x2
from my_csv
where x1 = 2
62
Clodoaldo Neto

COPYコマンドを使用して、入力する列を提供できます。そのようです:

\copy your_table (x2,x5,x7,x10) FROM '/path/to/your-file.csv' DELIMITER ',' CSV;

ドキュメントはこちらCOPYコマンドの場合。

28
Julien

列のサブセットのみをロードするソリューションを追求するためにここに到着しましたが、どうやらそれは不可能です。したがって、awk(またはcut)を使用して、必要な列を新しいファイルnew_fileに抽出します。

$ awk '{print $2, $5, $7, $10}' file > new_file

new_fileをロードします。出力をpsqlに直接パイプすることができます:

$ cut -d \  -f 2,5,7,10 file | 
  psql -h Host -U user -c "COPY table(col1,col2,col3,col4) FROM STDIN DELIMITER ' '" database

\COPYではなく、COPYに注意してください。

9
James Brown

他の回答が指摘しているように、PGテーブルにコピーする列を指定することは可能です。ただし、CSVで列名を参照するオプションがない場合、列の順序が異なるテーブルにロードする以外にはほとんど役に立ちませんでした。

幸いなことに、Postgres 9.3の時点では、ファイルまたは標準入力からだけでなく、PROGRAMを使用したシェルコマンドからも列をコピーできます。

プログラム

実行するコマンド。 COPY FROMでは、入力はコマンドの標準出力から読み取られ、COPY TOでは、出力はコマンドの標準入力に書き込まれます。

コマンドはシェルによって呼び出されることに注意してください。したがって、信頼できないソースからのシェルコマンドに引数を渡す必要がある場合は、特別な意味を持つ特殊文字を削除またはエスケープするように注意する必要がありますシェル。セキュリティ上の理由から、固定コマンド文字列を使用するか、少なくともユーザー入力を渡さないようにすることをお勧めします。

これは、待ち望まれていた機能のために必要だった欠品です。たとえば、このオプションをcut(UNIXベースのシステム)と組み合わせて使用​​して、特定の列を順番に選択できます。

COPY my_table (x2, x5, x7, x10) FROM PROGRAM 'cut -d "," -f 2,5,7,10 /path/to/file.csv' WITH (FORMAT CSV, HEADER)

ただし、cutはCSVを操作するときにいくつかの制限があります:カンマ(またはその他の区切り文字)を含む文字列を適切に操作できず、名前で列を選択できません。

csvkitmillerなど、CSVファイルの操作に優れた他のオープンソースコマンドラインツールがいくつかあります。 millerを使用して名前で列を選択する例を次に示します。

COPY my_table (x2, x5, x7, x10) FROM PROGRAM 'mlr --csv lf cut -f x2,x5,x7,x10 /path/to/file.csv' WITH (FORMAT CSV, HEADER)

4
arredond

ジェームスブラウンの提案をさらに進めて、すべて1行で行うことができます。

catファイル| awk -F '、' '{print $ 2 "、" $ 5 "、" $ 7 "、" $ 10}' | psql -d db -c "STDIN csvヘッダーからMyTableをコピー"

0
Chris Lawton

スプレッドシート(​​ExcelまたはOpenOffice Calc)からpostgreSQLにデータをロードするには:

スプレッドシートページをCSVファイルとして保存します。推奨される方法は、OpenOffice Calcでスプレッドシートを開いて保存することです。 [テキストファイルにエクスポート]ウィンドウで、[Unicode(UTF8)として文字セット]、[フィールド区切り記号: "、"、およびテキスト区切り記号 "" "を選択します。アクティブなシートのみが保存されるというメッセージが表示されます。注:このファイルは、デスクトップではなくフォルダーに保存する必要があり、UTF8形式で保存する必要があります(dafaultによるpostgreSQLはUTF8エンコード用に強化されています)。デスクトップに保存すると、postgreSQLは「アクセスが拒否されました」というメッセージを表示し、アップロードしません。

PostgreSQLで、スプレッドシートと同じ列数の空のテーブルを作成します。

注:各列で、column-nameは同じでなければならず、データ型は同じでなければなりません。また、十分なフィールドで文字が変化するデータの長さに注意してください。

次に、postgreSQLのSQLウィンドウにコードを配置します。

e'C:\\ tmp \\ blabla.csv 'delimiters'、 'C​​SV HEADERから "ABC"。 "def"をコピーします。

注:ここで、C:\\ tmpはCSVファイル「blabla」が保存されているフォルダーです。 「ABC」。「def」はpostgreSQLで作成されたテーブルで、「ABC」はスキーマ、「def」は実際のテーブルです。次に、上部の緑色のボタンを押して「クエリを実行」します。 CSVテーブルにすべての列の先頭に見出しがある場合、「CSV HEADER」が必要です。

Everythigに問題がない場合、エラーメッセージは表示されず、CSVファイルのテーブルデータがpostgreSQLテーブルにロードされます。ただし、エラーメッセージがある場合は、次のようにします。

特定の列に対してデータが長すぎるというエラーメッセージが表示される場合は、列のサイズを増やします。これは主にキャラクターとキャラクターが変化する列で起こります。次に、「クエリの実行」コマンドを再度実行します。

データ型が特定の列と一致しないというエラーメッセージが表示されている場合は、postgreSQL table-columnのデータ型を変更してCSVテーブルのデータ型と一致させます。

あなたの場合、CSVファイルを作成した後、不要な列を削除し、postgreテーブルの列と一致させます。

0
Sagun

結果として、インポートされた行の数が重要でない場合は、次のこともできます。

2つのテーブルを作成します。

  • t1(x1 x2 x3 x4 x5 x6 x7 x8 x9 x10):csvファイルのすべての列を含む
  • t2(x2 x5 x7 x10):必要に応じて

次に作成:

  • 代わりにt2に目的の列を挿入し、この行がt1に挿入されないようにNULLを返すトリガー関数

  • この関数を呼び出すt1(各行の挿入前)のトリガー。

特に大きなCSVファイルでは、BEFORE INSERTトリガーは特定のプロパティを持つ行を事前に除外するのにも役立ちます。また、型変換も行うことができます。

0
Michael Kraxner