如何根据列名将数据从 CSV 复制到目标表?

Posted

技术标签:

【中文标题】如何根据列名将数据从 CSV 复制到目标表?【英文标题】:How can I copy data from CSV to a destination table based on column names? 【发布时间】:2021-05-19 15:40:41 【问题描述】:

上下文

我在 S3 中接收 CSV 文件,这些文件并不总是遵循相同的架构和/或顺序。例如,有时文件看起来像:

foo, bar, bla
hi , 007, 42
bye, 008, 44

但其他时候,它们可能看起来像(bar 可能会丢失):

foo,  bla
hi ,  42
bye,  44

现在假设我只对获取foo 列感兴趣,而不管那里还有什么。但我不能真正指望 CSV 中列的顺序。所以在某些日子foo 可能是第一列,但在其他日子foo 可能是第三列。顺便说一句,我使用Snowflake作为数据库。

我尝试过的事情

我创建了一个目标表,例如:

CREATE TABLE woof.meow (foo TEXT);

然后我尝试使用 Snowflake 的 COPY INTO 命令将数据从 CSV 复制到我创建的表中。这里的问题是,我尝试用与 Parquet 文件相同的方式(按列名匹配!),例如:

COPY INTO woof.meow 
FROM '@STAGES.MY_S3_BUCKET_STAGE/'
file_format = (
  TYPE=CSV,
  COMPRESSION=GZIP,
)
MATCH_BY_COLUMN_NAME = CASE_INSENSITIVE;

但遗憾的是我总是得到:error: Insert value list does not match column list expecting 1 but got 0

一些研究将我带到docs(关于MATCH_BY_COLUMN_NAME)的这一部分,发现不支持CSV:

This copy option is supported for the following data formats:

- JSON
- Avro
- ORC
- Parquet

预期目标

如何根据列名将STAGE(包含 s3 上的 csv 文件)中的数据复制到预先创建的表中?

如果需要,我很乐意提供任何进一步的信息。

【问题讨论】:

【参考方案1】:

您正在尝试将作为逗号分隔值文件数据的 CSV 插入到一个文本列中,据我所知,您在源数据文件中的列顺序应该与您在 Snowflake 中为目标表创建的列顺序相同,这意味着如果你有 foo , bar 和 bla 作为源 csv 文件中的列,那么你的目标表列也应该创建为单独的列,与源 csv 文件的顺序相同; 如果您不确定源文件中可能包含哪些列;我建议您将此文件转换为 JSON(这是我的选择,您也可以选择其他选项,例如 avro)并将该内容加载到 Snowflake 的 VARIANT 列中; 通过这种方式,您不必担心源文件中列的顺序,您可以将数据作为 JSON/AVRO 存储到目标表中,并使用 JSON 处理机制将 JSON 值转换为列。(将 JSON 展平以将其转换为关系表)`

【讨论】:

以上是关于如何根据列名将数据从 CSV 复制到目标表?的主要内容,如果未能解决你的问题,请参考以下文章

如何在将数据从 csv 复制到 sql 表时在目标表中插入 CurrentUserId 和 TenantId 字段

根据txt中的文件名将文件复制到目标文件夹中

如何使用第一行的列名将 CSV 导入 BigQuery 上的现有表?

如何使用 CSV 文件中的标题从 CSV 文件复制到 PostgreSQL 表?

如何根据 MySQL 中第三个表中存在的 id 将数据从一个表复制到另一个表?

如何将数据从一个表复制到另一个列数据类型不同的表?