首页 > 解决方案 > 如何从 pandas 读取动态 json 到 pyarrow.Table

问题描述

我有将从 api 接收的 json 对象,返回的 json 对象没有定义的规范。返回的 json 是一个嵌套的 json 对象。我想转换为 pyarrow 表以在 AWS Athena Hive Glue 数据目录中作为结构进行查询。对于一些返回的 json 对象,它工作得很好,我喜欢开发人员的 pyarrow +100 类型推断!

对于其他人,我收到一个不正确的 json 对象,其中一个字段是两种类型的联合,没有 pyarrows 问题,但我确实收到了这个我无法解决的错误。

错误

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "pyarrow/table.pxi", line 1479, in pyarrow.lib.Table.from_pandas
  File "/python/venv/lib/python3.7/site-packages/pyarrow/pandas_compat.py", line 591, in dataframe_to_arrays
    for c, f in zip(columns_to_convert, convert_fields)]
  File "/python/venv/lib/python3.7/site-packages/pyarrow/pandas_compat.py", line 591, in <listcomp>
    for c, f in zip(columns_to_convert, convert_fields)]
  File "/python/venv/lib/python3.7/site-packages/pyarrow/pandas_compat.py", line 577, in convert_column
    raise e
  File "/python/venv/lib/python3.7/site-packages/pyarrow/pandas_compat.py", line 571, in convert_column
    result = pa.array(col, type=type_, from_pandas=True, safe=safe)
  File "pyarrow/array.pxi", line 301, in pyarrow.lib.array
  File "pyarrow/array.pxi", line 83, in pyarrow.lib._ndarray_to_array
  File "pyarrow/error.pxi", line 84, in pyarrow.lib.check_status
pyarrow.lib.ArrowInvalid: ('Could not convert INTMED with type str: tried to convert to int', 'Conversion failed for column RawJson with type object')

这是 json 的示例,我删除了大约 150 个属性,再次是动态的。

{
    "response": {
        "result": "success",
        "message": "Request processed successfully",
        "content": {
            "EPISODE": {
                ...
                "PARENT1": {
                    "PARENT2": [
                        {
                            ...
                            "CHILD": {
                                "CHILD1": [
                                    {
                                        "SPECIALTY_CODE": 81,
                                    }
                                ]
                            },
                            ...
                        },
                        {
                            ...
                            "CHILD": {
                                "CHILD1": [
                                    {
                                        "SPECIALTY_CODE": "INTMED",
                                    }
                                ]
                            },
                            ...
                        }
                    ]
                },
                ...
            }
        }
    }
}

我正在运行的代码

test_data_json = <json above>
# failing on 'RawJson' column below which is datatype converted to struct<...>
json_data = json.dumps({
                'TestColumn': 'user1',
                'RawJson': test_data_json
                }).encode('utf-8')
            )
df = pd.DataFrame.from_records(json_data)
pa.Table.from_pandas(df)

是否只有选项可以在不指定架构的情况下完成这项工作?

架构的问题在于这是一个深度嵌套的对象,我不知道 api 是否会有其他属性,例如这个属性会改变。我想要的是一个推断模式,以在此处强制转换为 str 数据类型,或者可以识别这些模式问题,并且它们以编程方式指定模式,以便通过我自己的数据类型强制来减少错误。

标签: pythonpandasparquetaws-gluepyarrow

解决方案


推荐阅读