【问题标题】:COPY csv file with additionnal datas复制带有附加数据的 csv 文件
【发布时间】:2021-03-15 15:36:39
【问题描述】:

我有下表:

persons(id,id_tech,name,nationality,id_list)

还有一个 CSV 文件,其中包含列 id_tech、名称和国籍的数据。

像这样导入数据是有效的:

\copy persons(id_tech,name,nationality) FROM '/path/to/file.csv' DELIMITER ',' CSV

id_list 值不在 CSV 文件中,因为该文件必须在许多服务器上导入,而该 id 的值可能不同。

有没有办法在为特定列提供附加值的同时导入 CSV 文件?我在文档中找不到任何相关内容。

编辑--
请注意,我的所有命令都将在 C++(多平台)中使用 pqxx 执行。我试图避免编辑文件,因为它的大小。

编辑 2 --
我正在考虑以下方法:

  • 为我需要的字段创建一个具有正确默认值的临时表
  • 将文件导入此临时表
  • 将 tmp 复制到最终表格
  • 删除临时表

但我不确定性能。最大的导入可能接近 500K 行。

谢谢

【问题讨论】:

    标签: postgresql csv libpqxx postgresql-copy


    【解决方案1】:

    在 Linux 上,您可以使用例如 awk 将附加值字段添加到您的数据中,并使用 psql 从标准输入读取:

    $ cat copy.sql
    \copy persons(id_tech,name,nationality,extra_col) FROM '/dev/stdin' DELIMITER ',' CSV
    

    然后:

    $ awk '
    BEGIN {
        FS=OFS=","
    }
    {
        print $1,$2,$3,"additional value"
    }' file.csv | psql -h host -d database -f file.sql
    

    (在 PostgreSQL 12.4 上测试)

    【讨论】:

    • 感谢您的回答,但我不仅在 Linux 下与 c++ 中的 postgres 交互。我可以用 C++ 修改文件,但由于它们的大小,我想避免这种情况
    • 如果您无法从标准输入读取并需要从文件中读取,我想您只需在加载之前编辑文件或先加载到临时表。祝你好运。
    【解决方案2】:

    找到了一个看起来不错的解决方案。

    正如我的 OP 中所述,我使用 libpqxx 插入数据,所以我没有直接运行 COPY sql 请求,而是使用 pqxx::stream_to

    如果需要,我可以添加其他字段:

    pqxx::stream_to stream(w, mTable, std::vector<std::string>{"id_tech","name","nationality","extra_col"});
    csv::CSVReader reader(filePath);
    for (csv::CSVRow& row : reader) {
    
        stream << std::make_tuple(row[0].get<long long>(), row[1].get<std::string>(), row[2].get<std::string>(), custom_id);
    }
    stream.complete();
    

    大约需要 10 秒来导入 300K 行,这对我的需求来说很好。

    【讨论】:

      猜你喜欢
      • 2018-11-18
      • 1970-01-01
      • 2021-07-21
      • 1970-01-01
      • 2011-07-28
      • 2012-09-21
      • 2021-10-11
      • 1970-01-01
      相关资源
      最近更新 更多