无法将带有 json 字符串的 csv 从 S3 加载到 redshift

failing to load a csv with json string from S3 to redshift

我有一个 csv,其中的行如下所示:

2021-08-20,2021-10-04,2021-10-04,148355456455712,Accountname,USD,"[{'action_type': 'add_to_cart', 'value': '266.63', '1d_click': '266.63', '7d_click': '266.63'}, {'action_type': 'initiate_checkout', 'value': '213.03', '1d_click': '213.03', '7d_click': '213.03'}, {'action_type': 'view_content', 'value': '762.75', '1d_click': '762.75', '7d_click': '762.75'}, {'action_type': 'omni_add_to_cart', 'value': '266.63', '1d_click': '266.63', '7d_click': '266.63'}, {'action_type': 'omni_initiated_checkout', 'value': '213.03', '1d_click': '213.03', '7d_click': '213.03'}, {'action_type': 'omni_view_content', 'value': '762.75', '1d_click': '762.75', '7d_click': '762.75'}, {'action_type': 'add_to_cart', 'value': '266.63', '1d_click': '266.63', '7d_click': '266.63'}, {'action_type': 'initiate_checkout', 'value': '213.03', '1d_click': '213.03', '7d_click': '213.03'}]"

我正在尝试使用以下架构将此 CSV 加载到 redshift table:

Columns             Type    Nullable    Length  Precision

date_start          varchar true        256     256
date_stop           varchar true        256     256
created_time        varchar true        256     256
account_id          int8    true        19      19
account_name        varchar true        256     256
account_currency    varchar true        256     256
action_values       varchar true        256     256

我正在使用以下 DML 语句:

copy table_name
from 's3://bucket_name/subdirectory/filename.csv'
delimiter ','
ignoreheader 1
csv quote as '"'
dateformat 'auto'
timeformat 'auto'
access_key_id '...'
secret_access_key '...'
   ;

我收到这个错误: Load into table 'table_name' failed. Check 'stl_load_errors' system table for details.

当我查看 stl_load_errors table 时,我看到的是:

query   substring   line    value           err_reason

93558   ...         2   2021-08-20          Invalid digit, Value '[', Pos 0, Type: Long
93558   ...         2   2021-10-04          Invalid digit, Value '[', Pos 0, Type: Long
93558   ...         2   2021-10-04          Invalid digit, Value '[', Pos 0, Type: Long
93558   ...         2   148355456455712     Invalid digit, Value '[', Pos 0, Type: Long
93558   ...         2   Accountname         Invalid digit, Value '[', Pos 0, Type: Long
93558   ...         2   USD                 Invalid digit, Value '[', Pos 0, Type: Long

我只是想不通为什么它不起作用,但我猜它与 json 字符串有关。我也不明白这个“类型:长”是从哪里来的。

我试图避免使用 Json 文件作为输入...

有人能帮忙吗?

除了最后一个字段(json 数据)超过 256 个字符外,您的数据看起来确实合理(据我所知)。然而,这不是您显示的错误。 stl_load_errors 的格式不是 table 的格式,所以我假设您正在对问题中显示的 table 进行一些处理。 “Type:Long”指的是您的 table DDL 的 INT8 - INT8 也称为 Big Int 或 Long Int。

我认为您的问题是您没有指定 COPY 正在读取 CSV 文件并且默认格式为 DELIMITED。要让 Redshift COPY 遵循 CSV 规则,您需要指定文件格式为 CSV。具体来说,我怀疑双引号提供了您期望的数据值分组。

我解决了!

因为 Redshift 将每个 \' 解析为字符串,并且每个 \, 解析为分隔符(如果不在字符串中)。解决方案是将 json 字符串中的所有 \' 替换为 \",这样它看起来如下所示:

2021-08-20,2021-10-04,2021-10-04,148355456455712,Accountname,USD,'[{"action_type": "add_to_cart", "value": "266.63", "1d_click": "266.63", "7d_click": "266.63"}, {"action_type": "initiate_checkout", "value": "213.03", "1d_click": "213.03", "7d_click": "213.03"}, {"action_type": "view_content", "value": "762.75", "1d_click": "762.75", "7d_click": "762.75"}, {"action_type": "omni_add_to_cart", "value": "266.63", "1d_click": "266.63", "7d_click": "266.63"}, {"action_type": "omni_initiated_checkout", "value": "213.03", "1d_click": "213.03", "7d_click": "213.03"}, {"action_type": "omni_view_content", "value": "762.75", "1d_click": "762.75", "7d_click": "762.75"}, {"action_type": "add_to_cart", "value": "266.63", "1d_click": "266.63", "7d_click": "266.63"}, {"action_type": "initiate_checkout", "value": "213.03", "1d_click": "213.03", "7d_click": "213.03"}]'

因为我 sed pandas 预处理代码如下:

for col in array_cols:
    df[col] = df[col].str.replace('\'','\"')