10列のCSVファイルがあります。 4列のPostgreSQLテーブルを作成した後、10列の一部をテーブルにコピーします。
cSVテーブルの列は次のようなものです。
x1 x2 x3 x4 x5 x6 x7 x8 x9 x10
postgreSQLテーブルの列は次のようになります。
x2 x5 x7 x10
入力ファイルのすべての列を含む一時テーブルを作成します
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
COPY
コマンドを使用して、入力する列を提供できます。そのようです:
\copy your_table (x2,x5,x7,x10) FROM '/path/to/your-file.csv' DELIMITER ',' CSV;
ドキュメントはこちらCOPY
コマンドの場合。
列のサブセットのみをロードするソリューションを追求するためにここに到着しましたが、どうやらそれは不可能です。したがって、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
に注意してください。
他の回答が指摘しているように、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を操作するときにいくつかの制限があります:カンマ(またはその他の区切り文字)を含む文字列を適切に操作できず、名前で列を選択できません。
csvkit
やmiller
など、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)
ジェームスブラウンの提案をさらに進めて、すべて1行で行うことができます。
catファイル| awk -F '、' '{print $ 2 "、" $ 5 "、" $ 7 "、" $ 10}' | psql -d db -c "STDIN csvヘッダーからMyTableをコピー"
スプレッドシート(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'、 'CSV HEADERから "ABC"。 "def"をコピーします。
注:ここで、C:\\ tmpはCSVファイル「blabla」が保存されているフォルダーです。 「ABC」。「def」はpostgreSQLで作成されたテーブルで、「ABC」はスキーマ、「def」は実際のテーブルです。次に、上部の緑色のボタンを押して「クエリを実行」します。 CSVテーブルにすべての列の先頭に見出しがある場合、「CSV HEADER」が必要です。
Everythigに問題がない場合、エラーメッセージは表示されず、CSVファイルのテーブルデータがpostgreSQLテーブルにロードされます。ただし、エラーメッセージがある場合は、次のようにします。
特定の列に対してデータが長すぎるというエラーメッセージが表示される場合は、列のサイズを増やします。これは主にキャラクターとキャラクターが変化する列で起こります。次に、「クエリの実行」コマンドを再度実行します。
データ型が特定の列と一致しないというエラーメッセージが表示されている場合は、postgreSQL table-columnのデータ型を変更してCSVテーブルのデータ型と一致させます。
あなたの場合、CSVファイルを作成した後、不要な列を削除し、postgreテーブルの列と一致させます。
結果として、インポートされた行の数が重要でない場合は、次のこともできます。
2つのテーブルを作成します。
次に作成:
代わりにt2に目的の列を挿入し、この行がt1に挿入されないようにNULLを返すトリガー関数
この関数を呼び出すt1(各行の挿入前)のトリガー。
特に大きなCSVファイルでは、BEFORE INSERTトリガーは特定のプロパティを持つ行を事前に除外するのにも役立ちます。また、型変換も行うことができます。