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 '"';
NOPE:ERROR: invalid input syntax for type numeric: ""
copy mytable from 'myfile.csv' with csv header quote '"' null '""';
NOPE:ERROR: CSV quote character must not appear in the NULL specification
有什么可以做的?在运行COPY
之前删除文件中的所有双引号?可以做到这一点,但我认为这是一个非常普遍的问题的正确解决方案。
答案 0 :(得分:11)
虽然有些数据库产品将空字符串视为NULL值,但标准表明它们是不同的,PostgreSQL将它们视为不同。
最好能够生成具有明确表示的CSV文件。虽然可以使用sed或其他东西将文件过滤到良好的格式,但另一个选项是COPY
数据输入到text
列可以接受的表中空字符串,然后填充目标表。 NULLIF
函数可以帮助:http://www.postgresql.org/docs/9.1/interactive/functions-conditional.html#FUNCTIONS-NULLIF - 如果两个参数匹配则返回NULL,如果不匹配则返回第一个值。因此,像NULLIF(txtcol, '')::numeric
这样的东西可能适合你。
答案 1 :(得分:6)
作为替代方案,使用
sed 's/""//g' myfile.csv > myfile-formatted.csv
psql
# copy mytable from 'myfile-formatted.csv' with csv header;
也可以。
答案 2 :(得分:2)
我认为你需要做的就是:
COPY mytable from '/dir/myfile.csv' DELIMITER ',' NULL '' WITH CSV HEADER QUOTE ;
答案 3 :(得分:2)
COPY mytable from '/dir/myfile.csv' DELIMITER ',' NULL ''
WITH CSV HEADER FORCE QUOTE *;
答案 4 :(得分: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()