23

CSV 行の例:

"2012","Test User","ABC","First","71.0","","","0","0","3","3","0","0","","0","","","","","0.1","","4.0","0.1","4.2","80.8","847"

"First" の後の値はすべて数値列です。多くの NULL 値がそのまま引用されています。

COPY の試行:

copy mytable from 'myfile.csv' with csv header quote '"';

いいえ:ERROR: invalid input syntax for type numeric: ""

まあ、そうだろう。ヌル値です。COPY での試行 2:

copy mytable from 'myfile.csv' with csv header quote '"' null '""';

いいえ:ERROR: CSV quote character must not appear in the NULL specification

何をするのですか?COPY?を実行する前に、ファイルからすべての二重引用符を取り除きます。それはできますが、信じられないほど一般的な問題に違いない適切な解決策があると考えました。

4

5 に答える 5

13

一部のデータベース製品は空の文字列を NULL 値として扱いますが、標準ではそれらは別個のものであると述べており、PostgreSQL はそれらを別個のものとして扱います。

明確な表現で CSV ファイルを生成できれば最高です。sed などを使用してファイルを適切な形式にフィルター処理することもできますが、他のオプションは、が空の文字列を受け入れることができるCOPYテーブルにデータを入力してから、ターゲット テーブルにデータを入力することです。text関数はそれNULLIFを助けるかもしれません: http://www.postgresql.org/docs/9.1/interactive/functions-conditional.html#FUNCTIONS-NULLIF -- 両方の引数が一致する場合は NULL を返し、一致しない場合は最初の値を返します。 t。したがって、次のようなものNULLIF(txtcol, '')::numericがうまくいくかもしれません。

于 2012-04-17T17:58:33.343 に答える
7

代わりに、

sed 's/""//g' myfile.csv > myfile-formatted.csv
psql 
# copy mytable from 'myfile-formatted.csv' with csv header;

同様に動作します。

于 2012-09-05T18:24:30.777 に答える
5

ここで行う必要があるのは次のことだけだと思います。

COPY mytable from '/dir/myfile.csv' DELIMITER ',' NULL '' WITH CSV HEADER QUOTE ;
于 2013-01-11T15:17:03.367 に答える
0

これはPython 3.8.Xでうまくいきました

import psycopg2
import csv
from io import StringIO
db_conn = psycopg2.connect(host=t_host, port=t_port,
                           dbname=t_dbname, user=t_user, password=t_pw)
cur = db_conn.cursor()

csv.register_dialect('myDialect',
                     delimiter=',',
                     skipinitialspace=True,
                     quoting=csv.QUOTE_MINIMAL)

with open('files/emp.csv') as f:
    next(f) 
    reader = csv.reader(f, dialect='myDialect') 
    buffer = StringIO()
    writer = csv.writer(buffer, dialect='myDialect') 
    writer.writerows(reader) 
    buffer.seek(0)
    cur.copy_from(buffer, 'personnes', sep=',', columns=('nom', 'prenom', 'telephone', 'email'))
    db_conn.commit()
于 2020-05-23T14:14:05.990 に答える