Postgresql:COPY FROM csv文件,其中包含缺失的列

时间:2011-01-04 09:10:29

标签: postgresql data-warehouse etl

我在CSV文件中有数十亿行数据。每行可以包含10到20列的任何内容。我想使用COPY FROM将数据加载到包含20列的表中。如果特定的CSV行只包含10列数据,那么我希望COPY FROM将其余列(缺少值)设置为NULL。我在CREATE TABLE语句中的每一列上指定DEFAULT NULL。

我的问题: 可以使用COPY FROM完成吗?

编辑:Greenplum(基于PostgreSQL的数据库)有一个名为FILL MISSING FIELDS的开关,它完成了我所描述的内容(参见他们的文档here)。你会为PostgreSQL推荐哪些变通方法?

4 个答案:

答案 0 :(得分:2)

编写一个预处理脚本,只是在没有足够列的行上添加一些额外的逗号,或者将CSV转换为TSV(制表符分隔)并将“\ N”放在额外的列中。 / p>

答案 1 :(得分:1)

我认为你不能让COPY FROM在同一个文件中处理不同数量的列。

如果始终缺少相同的10列,则解决方法可能是首先将所有内容加载到具有单个text列的临时表中。

之后,您可以使用SQL来拆分行并提取列,如下所示:

INSERT INTO target_table (col1, col2, col3, col4, col5, ...)
SELECT columns[1], columns[2], ...
FROM ( 
  SELECT string_to_array(big_column, ',') as columns
    FROM staging_table 
) t
WHERE array_length(columns) = 10

然后使用array_length(columns) = 20

执行类似的操作

答案 2 :(得分:1)

etldata-warehouse的背景下 - 我的建议是实际避免您正在寻找的“捷径”。

ETL是一个过程,经常以ECCD(Extract,Clean,Conform,Deliver)的形式实施。您可以将这些文件视为“已提取”,因此只需实施数据清理并符合不同的步骤 - 您将需要一些额外的磁盘空间。所有符合的文件都应该具有“最终”(所有列)结构。然后传递(COPY FROM)那些一致的文件。

通过这种方式,您还可以记录ETL过程以及每个步骤中缺少的字段会发生什么。

通常的做法是归档(磁盘,DVD)原始客户文件和一致的版本,以便进行审计和调试。

答案 3 :(得分:0)

来自PostgreSQL manual

  

如果有的话,COPY FROM会引发错误   输入文件的行包含更多   列数少于预期。

阅读CSV文件的第一行,查看您必须在COPY语句中命名的列数。