OS X 10.6.8でPostgreSQL 9.2.6を実行しています。列ヘッダー付きのCSVファイルからデータベースにデータをインポートしたいと思います。これを行うには、COPY
ステートメントを使用しますが、CSVファイルの各列に対応する列を含むテーブルを最初に手動で作成した場合のみです。 CSVファイルのヘッダーに基づいてこのテーブルを自動的に作成する方法はありますか?
この質問 試した
_COPY test FROM '/path/to/test.csv' CSV HEADER;
_
しかし、私はこのエラーを受け取ります:
_ERROR: relation "test" does not exist
_
そして、最初に列のないテーブルを作成した場合:
CREATE TABLE test ();
私は得る:
_ERROR: extra data after last expected column
_
PostgreSQLに何も見つかりません COPY documentation テーブルの自動作成について。ヘッダー付きのCSVファイルからテーブルを自動的に作成する他の方法はありますか?
COPYcannotがテーブルを作成するため、 COPY
ドキュメントには何も見つかりません。
それをCOPY
する前に行う必要があります。
CsvファイルからPostgresにテーブルをインポートする非常に優れたツールがあります。これはpgfutterと呼ばれるコマンドラインツールです( Windows、Linuxなどのバイナリを使用 )。その大きな利点の1つは、属性/列名も認識することです。
ツールの使用方法は簡単です。たとえば、myCSVfile.csv
をインポートする場合:
pgfutter --db "myDatabase" --port "5432" --user "postgres" --pw "mySecretPassword" csv myCSVfile.csv
これにより、csvファイルのヘッダーから取得した列名を持つテーブル(myCSVfile
と呼ばれる)が作成されます。さらに、データ型は既存のデータから識別されます。
いくつかの注意:コマンドpgfutter
は、使用するバイナリによって異なります。 pgfutter_windows_AMD64.exe
(このコマンドを頻繁に使用する場合は名前を変更してください)の場合があります。上記のコマンドはコマンドラインウィンドウで実行する必要があります(たとえば、Windowsではcmd
を実行し、pgfutter
にアクセスできることを確認します)。別のテーブル名にしたい場合は、--table "myTable"
;を追加します。特定のデータベーススキーマを選択するには、--schema "mySchema"
を使用します。外部データベースにアクセスする場合は、--Host "myHostDomain"
を使用します。
pgfutter
をmyFile
にインポートするmyTable
のより複雑な例は次のとおりです。
pgfutter --Host "localhost" --port "5432" --db "myDB" --schema "public" --table "myTable" --user "postgres" --pw "myPwd" csv myFile.csv
ほとんどの場合、インポート後にいくつかのデータ型を(テキストから数値に)変更します。
alter table myTable
alter column myColumn type numeric
using (trim(myColumn)::numeric)
2番目のアプローチがありますが、これは here (mmattから)です。基本的に、Postgres内で関数を呼び出します(最後の引数は列の数を指定します)。
select load_csv_file('myTable','C:/MyPath/MyFile.csv',24)
これがmmattの関数コードです。公開スキーマに取り組んでいるので、少し変更する必要がありました。 (コピーしてPgAdmin SQL Editorに貼り付けて実行し、関数を作成します)
CREATE OR REPLACE FUNCTION load_csv_file(
target_table text,
csv_path text,
col_count integer)
RETURNS void AS
$BODY$
declare
iter integer; -- dummy integer to iterate columns with
col text; -- variable to keep the column name at each iteration
col_first text; -- first column name, e.g., top left corner on a csv file or spreadsheet
begin
set schema 'public';
create table temp_table ();
-- add just enough number of columns
for iter in 1..col_count
loop
execute format('alter table temp_table add column col_%s text;', iter);
end loop;
-- copy the data from csv file
execute format('copy temp_table from %L with delimiter '','' quote ''"'' csv ', csv_path);
iter := 1;
col_first := (select col_1 from temp_table limit 1);
-- update the column names based on the first row which has the column names
for col in execute format('select unnest(string_to_array(trim(temp_table::text, ''()''), '','')) from temp_table where col_1 = %L', col_first)
loop
execute format('alter table temp_table rename column col_%s to %s', iter, col);
iter := iter + 1;
end loop;
-- delete the columns row
execute format('delete from temp_table where %s = %L', col_first, col_first);
-- change the temp table name to the name given as parameter, if not blank
if length(target_table) > 0 then
execute format('alter table temp_table rename to %I', target_table);
end if;
end;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION load_csv_file(text, text, integer)
OWNER TO postgres;
注:エンコードに関連するテキストファイルのインポートには一般的な問題があります。 csvファイルはUTF-8形式である必要があります。ただし、エンコードを実行しようとするプログラムでは、これが完全に達成されない場合があります。 Notepad ++でファイルを開き、ANSIに変換してUTF8に戻すことで、この問題を克服しました。
私はこの手順でそれを達成しました:
iconv -f ISO-8859-1 -t UTF-8 file.txt -o file.csv
#!/usr/bin/env python3
import csv, os
#pip install python-slugify
from slugify import slugify
origem = 'file.csv'
destino = 'file.sql'
arquivo = os.path.abspath(origem)
d = open(destino,'w')
with open(origem,'r') as f:
header = f.readline().split(';')
head_cells = []
for cell in header:
value = slugify(cell,separator="_")
if value in head_cells:
value = value+'_2'
head_cells.append(value)
#cabecalho = "{}\n".format(';'.join(campos))
#print(cabecalho)
fields= []
for cell in head_cells:
fields.append(" {} text".format(cell))
table = origem.split('.')[0]
sql = "create table {} ( \n {} \n);".format(origem.split('.')[0],",\n".join(fields))
sql += "\n COPY {} FROM '{}' DELIMITER ';' CSV HEADER;".format(table,arquivo)
print(sql)
d.write(sql)
3.スクリプトを実行します
python3 importar.py
オプション:sqlスクリプトを編集してフィールドタイプを調整します(デフォルトではすべてテキストです)
Sudo -H -u postgres bash -c "psql mydatabase < file.sql"
1つのテーブルについて、Webで見つかる多くの優れたコンバーターの1つを使用して、非常に簡単かつ迅速にオンラインでやりました。 google csvをオンラインでsqlに変換する のいずれかを選択します。