【问题标题】:importing csv with psql \copy, modify data as it comes使用 psql \copy 导入 csv,修改数据
【发布时间】:2015-03-13 01:41:25
【问题描述】:

我经常需要将 csv 导入 postgres,并且通常使用来自 psql\copy 命令。它通常看起来像这样

\copy tbl FROM import.csv CSV 

我有两个常见的问题,我觉得可能会有类似的答案。

  1. 在日期字符串进入TIMESTAMP 字段时对其进行解析
  2. INTEGER 字段中的空字符串导致错误

在这两种情况下都需要进行少量修改,但我当前的解决方案是创建加载表,所有字段都为 VARCHAR 类型,然后创建另一个具有正确架构的表。然后我使用\copy

CREATE TABLE loading_tbl (
    datefield VARCHAR,
    integerfield VARCHAR
);    

CREATE TABLE tbl (
    datefield TIMESTAMP,
    integerfield INTEGER
);

\copy loading_tbl FROM import.csv CSV

INSERT INTO tbl (datefield, integerfield)
SELECT
    to_timestamp(datefield, 'YYYY-Mon, DAY HH24:MI a.m'),
    integerfield::INTEGER
FROM loading_tbl;

DROP TABLE loading_tbl;

这是最好的方法还是有更简单的方法?创建两个表有点痛苦,尤其是随着字段数量的增加。

【问题讨论】:

    标签: postgresql csv psql


    【解决方案1】:

    另一种选择是使用脚本语言来执行ETL。这可能更容易推理和/或开销更少,具体取决于您的具体需求。

    例如,您可以使用 Pythoncsvpsycopg2 模块与 CSV 文件进行交互和 Postgres 数据库,分别执行任何必要的 ETLpsycopg2 通常会为您处理时间戳字符串到实际的Postgres 时间戳转换(假设它是一个公认的时间戳字符串,其中有多种类型)。

    对于 CSV 中有字段在 Postgres 中为整数但在 CSV 中为空字符串的情况,在 Python 脚本,您可以检查空字符串值并将它们分配给 Postgres 中的 NULL

    我最近使用 Python 做了类似的事情,效果很好。您在问题中的解决方案最大的胜利可能是不需要过渡表,因为 ETL 可以在脚本中完成,然后通过 Postgres 发送到 psycopg2.

    如果您的 ETL 需求不大,即仅限于您上面提供的示例,则可能值得坚持使用纯 SQL。对此的一项改进是使用temp table(对于loading_tbl)而不是常规表。这样您就无需担心在 ETL 处理数据后删除它。

    【讨论】:

    • 感谢您的回复。为了简化简单的导入,引入脚本语言似乎是一种倒退。不过,使用 python 之类的东西可以更灵活地处理类型。如果没有更简单的解决方案,也许最好的解决方案是使用 python 之类的通用命令来默认处理这些情况。
    • 当然,没问题。也许你应该关注我列出的第二个选项,使用temp tables。就不需要担心之后清理桌子而言,这应该会简化一些事情。如果您的 ETL 案例是您上面列出的,使用temp tables 似乎是可行的。如果他们参与更多,那么您可能需要考虑引入脚本语言,或者至少是 PL/pgSQL
    猜你喜欢
    • 1970-01-01
    • 2019-02-22
    • 1970-01-01
    • 1970-01-01
    • 2017-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-11
    相关资源
    最近更新 更多