COPY
を実行すると、ERROR: invalid input syntax for integer: ""
エラーメッセージ。私は何が欠けていますか?
僕の /tmp/people.csv
ファイル:
"age","first_name","last_name"
"23","Ivan","Poupkine"
"","Eugene","Pirogov"
僕の /tmp/csv_test.sql
ファイル:
CREATE TABLE people (
age integer,
first_name varchar(20),
last_name varchar(20)
);
COPY people
FROM '/tmp/people.csv'
WITH (
FORMAT CSV,
HEADER true,
NULL ''
);
DROP TABLE people;
出力:
$ psql postgres -f /tmp/sql_test.sql
CREATE TABLE
psql:sql_test.sql:13: ERROR: invalid input syntax for integer: ""
CONTEXT: COPY people, line 3, column age: ""
DROP TABLE
トリビア:
エラー:整数の入力構文が無効です: ""
""
は有効な整数ではありません。 PostgreSQLは、CSVではデフォルトで引用符なし空白フィールドをnullとして受け入れますが、""
は次のようになります。
SELECT ''::integer;
同じ理由で失敗します。
Null整数の引用された空の文字列のようなものを含むCSVを処理したい場合は、それを少し上にできるプリプロセッサを介してPostgreSQLに供給する必要があります。 PostgreSQLのCSV入力は、CSVの奇妙で素晴らしい悪用のすべてを理解していません。
オプションが含まれます:
csv
モジュール、Perl Text::CSV
など、前処理します。私はあなたのcsvファイルを次のように変更する方が良いと思います:
"age","first_name","last_name"
23,Ivan,Poupkine
,Eugene,Pirogov
次のようにテーブルを定義することもできます
CREATE TABLE people (
age varchar(20),
first_name varchar(20),
last_name varchar(20)
);
コピー後、空の文字列を変換できます。
select nullif(age, '')::int as age, first_name, last_name
from people
「|」の読み込み時にこのエラーが発生しました入力ファイルに「」文字はありませんでしたが、CSVファイルを区切りました。FORMATを指定するのを忘れていたことがわかりました。
COPY ... FROM ... WITH(FORMAT CSV、DELIMITER '|')。
Postgresで同じエラーが発生しました.sql
ファイルにCOPY
ステートメントが含まれていますが、私のファイルはコンマ区切りおよび引用符ではなくタブ区切りでした。
私の間違いは、githubからファイルの内容を熱心にコピー/貼り付けたことですが、そのプロセスですべてのタブがスペースに変換されたため、エラーになりました。適切なコピーを取得するには、生ファイルをダウンロードして保存する必要がありました。
csvfix
を使用してこれを行うことになりました:
csvfix map -fv '' -tv '0' /tmp/people.csv > /tmp/people_fixed.csv
どの列がinteger
またはfloat
であるかが確実にわかっている場合は、それらだけを指定できます。
csvfix map -f 1 -fv '' -tv '0' /tmp/people.csv > /tmp/people_fixed.csv
正確な列を指定しないと、明らかな副作用が発生する可能性があり、空の文字列が0
文字を含む文字列に変換されます。
整数列のヌルとして引用符で囲まれたヌル文字列「」を解決する方法があります。FORCE_NULLオプションを使用します。
\copy table_name FROM 'file.csv' with (FORMAT CSV, FORCE_NULL(column_name));
postgresqlドキュメントを参照してください https://www.postgresql.org/docs/current/static/sql-copy.html
CREATE TABLE people (
first_name varchar(20),
age integer,
last_name varchar(20)
);
"first_name"、 "age"、 "last_name" Ivan、23、Poupkine Eugene , Pirogov
(区切り文字「;」、null '')で'file.csv'
から人をコピーします。
select * from people;
最初の列だけで.....
これは、ソースcsvファイルを変更しなくても機能するはずです。
alter table people alter column age type text;
copy people from '/tmp/people.csv' with csv;