将JSON数据加载到AWS Redshift会导致NULL值

时间:2015-06-30 01:24:45

标签: amazon-web-services amazon-redshift

我正在尝试执行加载/复制操作,以便将数据从S3存储桶中的JSON文件直接导入Redshift。 COPY操作成功,在COPY之后,表具有正确的行/记录数,但每条记录都为NULL!

加载需要预期的时间,COPY命令返回OK,Redshift控制台报告成功且没有错误......但是如果我从表中执行简单查询,它只返回NULL值。

JSON非常简单+平坦,格式正确(根据我在此处找到的示例:http://docs.aws.amazon.com/redshift/latest/dg/r_COPY_command_examples.html

基本上,每行一行,格式如下:

{ "col1": "val1", "col2": "val2", ... }
{ "col1": "val1", "col2": "val2", ... }
{ "col1": "val1", "col2": "val2", ... }

我尝试过根据JSON对象中的值和数据类型重写架构,以及从未压缩文件复制。我想也许JSON在加载时没有被正确解析,但如果无法解析对象,它可能会引发错误。

我的COPY命令如下所示:

copy events from 's3://mybucket/json/prefix' 
with credentials 'aws_access_key_id=xxx;aws_secret_access_key=xxx'
json 'auto' gzip;

任何指导将不胜感激!感谢。

4 个答案:

答案 0 :(得分:18)

所以我发现了原因 - 这在我原帖中提供的描述中并不明显。

在Redshift中创建表时,列名称将转换为小写。 执行COPY操作时,列名称区分大小写。

我一直在尝试加载的输入数据是使用camelCase作为列名,因此当我执行COPY时,列与定义的模式(现在使用所有小写列名称)不匹配

但该操作不会引发错误。它只会在所有不匹配的列中留下NULL(在本例中为所有列)

希望这有助于避免同样的混乱!

答案 1 :(得分:1)

这可能是因为 redshift 表的列名是小写的,而 JSON 文件中的列名是大写的(或驼峰式的)。作为一种解决方法,我们可以使用 'auto ignorecase' 而不是 'auto' 选项,并且 redshift 尝试匹配相应的列。 https://docs.aws.amazon.com/en_us/redshift/latest/dg/copy-parameters-data-format.html#copy-json

复制参数部分提到了信息。

答案 2 :(得分:0)

对于JSON数据对象不直接与列名对应的情况,您可以使用JSONPaths文件将JSON元素映射到TimZ所提及的列,并描述here

答案 3 :(得分:0)

  

COPY将JSON源数据中的数据元素映射到其中的列   通过匹配源中的对象键或名称来目标表   名称/值对与目标表中列的名称。的   匹配区分大小写。 Amazon Redshift表中的列名称为   总是小写,因此当您使用“自动”选项时,匹配JSON   字段名称也必须小写。如果不是JSON字段名称键   全部小写,您可以使用JSONPaths文件显式映射列   名称到JSON字段名称键。

解决方案是使用jsonpath

示例json:

{
"Name": "Major",
"Age": 19,
"Add": {
"street":{
"st":"5 maint st",
"ci":"Dub"
},
"city":"Dublin"
},

"Category_Name": ["MLB","GBM"]

}

示例表:

(
name varchar,
age int,
address varchar,
catname varchar
);

示例jsonpath:

{
"jsonpaths": [
"$['Name']",
"$['Age']",
"$['Add']",
"$['Category_Name']"
]
}

示例复制代码:

copy customer --redshift code
from 's3://mybucket/customer.json'
iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole'
json from 's3://mybucket/jpath.json' ; -- Jsonpath file to map fields

示例取自here