【问题标题】:Load NULL TIMESTAMP with TIME ZONE using COPY FROM in PostgreSQL在 PostgreSQL 中使用 COPY FROM 加载带有 TIME ZONE 的 NULL TIMESTAMP
【发布时间】:2015-02-20 04:19:05
【问题描述】:

我有一个 CSV 文件,我正在尝试使用 COPY FROM 命令将其加载到 PostgreSQL 9.2.4 数据库中。特别是有一个时间戳字段允许为空,但是当我加载“空值”(实际上只是"")时,我收到以下错误:

ERROR:  invalid input syntax for type timestamp with time zone: ""

一个示例 CSV 文件如下所示:

id,name,joined
1,"bob","2013-10-02 15:27:44-05"
2,"jane",""

SQL 如下所示:

CREATE TABLE "users"
(
    "id" BIGSERIAL NOT NULL PRIMARY KEY,
    "name" VARCHAR(255),
    "joined" TIMESTAMP WITH TIME ZONE,
);

COPY "users" ("id", "name", "joined")
    FROM '/path/to/data.csv'
    WITH (
        ENCODING 'utf-8',
        HEADER 1,
        FORMAT 'csv'
    );

根据documentation,空值应该用一个不能包含引号字符的空字符串来表示,在这种情况下是双引号("):

指定表示空值的字符串。默认为文本格式的 \N(反斜杠-N),以及 CSV 格式的不带引号的空字符串。在您不想区分空字符串和空字符串的情况下,您可能更喜欢使用文本格式的空字符串。使用二进制格式时不允许使用此选项。

注意:在使用 COPY FROM 时,任何与此字符串匹配的数据项都将存储为空值,因此您应确保使用与 COPY TO 相同的字符串。

我尝试了NULL '' 选项,但这似乎没有任何影响。请给点建议!

【问题讨论】:

  • 一如既往地,请提供您的 Postgres 版本。
  • 嗯,9.2.4 在我的本地机器上。如果我使用的是 9.4,你认为 FORCE_NULL 会起作用吗?
  • 没错。表明在此类问题中声明您的 Postgres 版本总是很重要。

标签: postgresql csv


【解决方案1】:

不带引号的空字符串正常工作:

id,name,joined
1,"bob","2013-10-02 15:27:44-05"
2,"jane",

select * from users;
id | name |         joined
----+------+------------------------
 1 | bob  | 2013-10-03 03:27:44+07
 2 | jane |

也许使用 sed 将 "" 替换为空字符串会更简单。

【讨论】:

  • 好的,我会考虑的 - 问题是这些 CSV 来自外部来源,而我不是手动预处理所有内容的人 - 我没有真的想在下游添加一个额外的步骤。
  • 太棒了。谢谢你。
【解决方案2】:

Postgres 9.4+ 中COPY FROMFORCE_NULL 选项将是解决问题的最优雅方式。 Per documentation:

FORCE_NULL

将指定列的值与空字符串匹配,即使 它已被引用,如果找到匹配项,则将值设置为NULL。在 null 字符串为空的默认情况,这将转换为 将空字符串引用到NULL。此选项仅在 COPY FROM 中允许,并且仅在使用 CSV 格式时才允许。

当然,它会转换所有列中的所有匹配值。

在旧版本中,您可以COPY 到具有相同表布局的临时表 - 除了问题列的数据类型text。然后从那里修复违规值和INSERT

【讨论】:

    【解决方案3】:

    无法让它工作。最终使用了这个程序: http://neilb.bitbucket.org/csvfix/

    你可以用其他值替换空文件。

    例如,在您的情况下,第 3 列需要有一个时间戳值,所以我给它一个假值。在这种情况下,“1900-01-01 00:00:00”。如果需要,您可以在导入数据后删除或过滤掉它们。

    $CSVFIXHOME/csvfix  map -f 3 -fv '' -tv '1900-01-01 00:00:00'  -rsep ',' $YOURFILE > $FILEWITHDATES
    

    之后就可以导入新建的文件了。

    【讨论】:

      猜你喜欢
      • 2012-04-04
      • 2011-03-14
      • 2023-01-10
      • 2021-11-12
      • 2019-12-31
      • 2020-09-20
      • 2011-07-22
      • 1970-01-01
      • 2015-09-28
      相关资源
      最近更新 更多