68

运行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 9.2.4
4

12 回答 12

44

错误:整数的无效输入语法:“”

""不是有效的整数。PostgreSQL 在 CSV 中默认接受不带引号的空白字段为 null,但""就像这样写:

SELECT ''::integer;

并因同样的原因而失败。

如果你想处理包含空整数引用的空字符串之类的 CSV,你需要通过一个预处理器将它提供给 PostgreSQL,它可以稍微整理一下。PostgreSQL 的 CSV 输入无法理解 CSV 的所有奇怪而奇妙的可能滥用。

选项包括:

  • 将其加载到电子表格中并导出健全的 CSV;
  • 使用 Pythoncsv模块、PerlText::CSV等对其进行预处理;
  • 使用 Perl/Python/whatever 加载 CSV 并将其直接插入数据库
  • 使用 CloverETL、Talend Studio 或 Pentaho Kettle 等 ETL 工具
于 2013-08-18T10:57:21.103 回答
16

我认为最好更改您的 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
于 2013-08-18T10:58:12.350 回答
10

只是在寻找解决方案时遇到了这个问题并想添加我能够通过将“null”参数添加到 copy_from 调用来解决这个问题:

cur.copy_from(f, tablename, sep=',', null='')
于 2019-09-19T12:38:49.540 回答
8

加载“|”时出现此错误 分隔的 CSV 文件,尽管我的输入文件中没有 '"' 字符。结果我忘记指定 FORMAT:

复制 ... FROM ... WITH ( FORMAT CSV , DELIMITER '|')。

于 2018-03-11T00:09:43.113 回答
5

.sql我在带有COPY语句的 postgres 文件上遇到了同样的错误,但我的文件是制表符分隔的,而不是逗号分隔和带引号的

我的错误是我急切地从 github 复制/粘贴文件内容,但在该过程中,所有选项卡都转换为空格,因此出现错误。我必须下载并保存原始文件才能获得一份好的副本。

于 2015-08-31T15:02:42.550 回答
4

使用以下命令在一行中从 CSV 复制数据,而无需转换和更改数据类型。请用您的字符串替换“NULL”,这会在复制数据中产生错误

copy table_name from 'path to csv file' (format csv, null "NULL", DELIMITER ',', HEADER);
于 2019-12-31T09:25:48.337 回答
3
CREATE TABLE people (
  first_name varchar(20),
  age        integer,
  last_name  varchar(20)
);

"first_name","age","last_name" Ivan,23,Poupkine Eugene,,Pirogov

复制人 from 'file.csv'with (delimiter ';', null '');

select * from people;

就在第一列......

于 2018-10-16T12:06:48.243 回答
2

最终使用csvfix

csvfix map -fv '' -tv '0' /tmp/people.csv > /tmp/people_fixed.csv

如果您确定哪些列应该是integerfloat,您可以只指定它们:

csvfix map -f 1 -fv '' -tv '0' /tmp/people.csv > /tmp/people_fixed.csv

如果不指定确切的列,则可能会遇到明显的副作用,即空白字符串将转换为带有0字符的字符串。

于 2013-08-18T14:10:31.070 回答
2

这应该可以在您不修改源 csv 文件的情况下工作:

alter table people alter column age type text;
copy people from '/tmp/people.csv' with csv;
于 2017-08-24T18:05:04.250 回答
2

有一种方法可以解决“”,在整数列中引用的空字符串为空,使用 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

于 2018-10-01T22:14:43.913 回答
0

令人难以置信的是,我对相同错误的解决方案是重新排列列。对于其他执行上述解决方案但仍未解决错误的人。

我显然必须安排我的 CSV 文件中的列以匹配 PGADmin 中的表列表中的相同序列。

于 2020-10-17T21:13:41.457 回答
0

全部在 python 中(使用psycopg2),首先创建空表,然后使用copy_expert将 csv 加载到其中。它应该处理空值。

import psycopg2
conn = psycopg2.connect(host="hosturl", database="db_name", user="username", password="password")
cur = conn.cursor()
cur.execute("CREATE TABLE schema.destination_table ("
            "age integer, "
            "first_name varchar(20), "
            "last_name varchar(20)"
            ");")

with open(r'C:/tmp/people.csv', 'r') as f:
    next(f)  # Skip the header row. Or remove this line if csv has no header.
    conn.cursor.copy_expert("""COPY schema.destination_table FROM STDIN WITH (FORMAT CSV)""", f)
于 2020-11-04T16:40:26.850 回答