首页 > 解决方案 > 如何通过 pyarrow 使用用户定义的模式编写 Parquet

问题描述

当我执行以下代码时 - 出现以下错误ValueError: Table schema does not match schema used to create file

import pandas as pd
import pyarrow as pa
import pyarrow.parquet as pq


fields = [
    ('one', pa.int64()),
    ('two', pa.string(), False),
    ('three', pa.bool_())
]
schema = pa.schema(fields)

schema = schema.remove_metadata()
df = pd.DataFrame(
    {
        'one': [2, 2, 2],
        'two': ['foo', 'bar', 'baz'],
        'three': [True, False, True]
    }
)

df['two'] = df['two'].astype(str)

table = pa.Table.from_pandas(df, schema, preserve_index=False).replace_schema_metadata()
writer = pq.ParquetWriter('parquest_user_defined_schema.parquet', schema=schema)
writer.write_table(table)

标签: python-3.xpyarrow

解决方案


这适用于最新版本的 pyarrow (>=0.14.0),但我可以确认我也收到 pyarrow 0.13 的错误)。

原因是在从 pandas 到箭头的转换中没有保留架构的可空性的错误(请参阅https://issues.apache.org/jira/browse/ARROW-5169)。

使用 pyarrow 0.13:

>>> schema.field_by_name('two').nullable
False

>>> table.schema.field_by_name('two').nullable
True

这使得您指定schema的和传递给的表的架构write_table不匹配,从而给出您看到的错误。
这是在 0.14 中修复的,两者都会False在上面的输出中给出。

因此,您可以在nullable=False手动创建架构时删除 ,或更新到箭头 >= 0.14。


请注意,您正在将单个表写入单个parquet文件,您不需要手动指定架构(您在将pandas DataFrame转换为箭头表时已经指定了它,pyarrow将使用表的架构来编写拼花)。所以在简单的情况下,你也可以这样做:

pq.write_table(table, 'parquest_user_defined_schema.parquet')

附加说明:您需要 awriter.close()才能使您的示例完整。


推荐阅读