Python 转换 Apache Avro 数据为 Parquet 格式
前面尝试过用 Java 转换 Apache Avro 数据为 Parquet 格式,本文用 Python 来做同样的事情,并且加入 logicalType: date 类型的支持。本测试中的 Avro 数据也是由 Python 代码生成的。
重复一句 Avro 与 Parquet 的最粗略的区别:Avro 广泛的应用于数据的序列化,如 Kafka,它是基于行的格式,可被流式处理,而 Parquet 是列式存储格式的,适合于基于列的查询。
第一步,生成 Avro 数据文件 user.avro, 须先安装 fastavro
产生了一个 user.avro, 用 avro-tools 查看其中的数据与 schema
user.avro 数据文件中的 birthday 能识别为 logicalType: date 类型
用 parque-tools 查看生成的 user.parquet 文件的 schema 与数据
数据完全正确,并且 birthday 在 Parquet 的 schema 中仍然是 int32(DATE) 类型。
如果喜欢在 Python 中用 Apache 的 avro 库也没问题, 安装 avro
更简单的使用 pandavro 包读取 avro 文件的方式
安装 pyarrow 和 pandavro
执行代码只须 3 行。代码中虽未显式导入 pyarrow, 但内部会用到,所以必须安装 pyarrow
链接:
永久链接 https://yanbin.blog/python-convert-avro-to-parquet/, 来自 隔叶黄莺 Yanbin's Blog
[版权声明]
本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。
重复一句 Avro 与 Parquet 的最粗略的区别:Avro 广泛的应用于数据的序列化,如 Kafka,它是基于行的格式,可被流式处理,而 Parquet 是列式存储格式的,适合于基于列的查询。
第一步,生成 Avro 数据文件 user.avro, 须先安装 fastavro
pip install fastavro
生成 user.avro 的代码
1from datetime import date
2
3from fastavro import parse_schema, writer
4
5schema = {
6 "namespace": "data",
7 "type": "record",
8 "name": "User",
9 "fields": [
10 {"name": "id", "type": "int"},
11 {"name": "name", "type": "string"},
12 {"name": "birthday", "type": {"type": "int", "logicalType": "date"}}
13 ]
14}
15
16parsed_schema = parse_schema(schema)
17
18records = [
19 {'id': 100, 'name': 'Tom', 'birthday': date.today()},
20 {'id': 101, 'name': 'Jerry', 'birthday': date(2019, 4, 24)},
21]
22
23with open('user.avro', 'wb') as out:
24 writer(out, parsed_schema, records)产生了一个 user.avro, 用 avro-tools 查看其中的数据与 schema
1$ avro-tools getschema user.avro
2{
3 "type" : "record",
4 "name" : "User",
5 "namespace" : "data",
6 "fields" : [ {
7 "name" : "id",
8 "type" : "int"
9 }, {
10 "name" : "name",
11 "type" : "string"
12 }, {
13 "name" : "birthday",
14 "type" : {
15 "type" : "int",
16 "logicalType" : "date"
17 }
18 } ]
19}
20$ avro-tools tojson user.avro
21{"id":100,"name":"Tom","birthday":18747}
22{"id":101,"name":"Jerry","birthday":18010}user.avro 数据文件中的 birthday 能识别为 logicalType: date 类型
转换 Avro 为 Parquet
先安装 pandaspip install pyarrow pandas转换代码
1import pandas as pd
2from fastavro import reader
3
4
5def process(records):
6 df = pd.DataFrame.from_records(records)
7 df.to_parquet('user.parquet')
8
9
10with open('user.avro', 'rb') as fo:
11 avro_reader = reader(fo)
12 rs = [r for r in avro_reader]
13 process(rs)用 parque-tools 查看生成的 user.parquet 文件的 schema 与数据
1$ parquet-tools schema user.parquet
2message schema {
3 optional int64 id;
4 optional binary name (STRING);
5 optional int32 birthday (DATE);
6}
7
8$ parquet-tools cat --json user.parquet
9{"id":100,"name":"Tom","birthday":18747}
10{"id":101,"name":"Jerry","birthday":18010}数据完全正确,并且 birthday 在 Parquet 的 schema 中仍然是 int32(DATE) 类型。
如果喜欢在 Python 中用 Apache 的 avro 库也没问题, 安装 avro
pip install avro读取记录的代码如下
1from avro.datafile import DataFileReader
2from avro.io import DatumReader
3with open('user.avro', 'rb') as fo:
4 reader = DataFileReader(fo, DatumReader())
5 rs = [r for r in reader]
6 process(rs)更简单的使用 pandavro 包读取 avro 文件的方式
安装 pyarrow 和 pandavro
pip install pyarrow pandavro会连带安装多个包,用 pip freeze 看下
$ pip freeze读取 avro 的代码
fastavro==1.4.0
numpy==1.20.2
pandas==1.2.4
pandavro==1.6.0
pyarrow==4.0.0
python-dateutil==2.8.1
pytz==2021.1
six==1.15.0
1import pandavro as pdx
2
3rs = pdx.from_avro('user.avro')
4process(rs)最后汇总一下如何最简单的转换 Avro 文件为 Parquet 格式
须安装的插件pip install pyarrow pandas完整转换 avro 文件为 parquet 文件代码如下
1import pandas as pd
2import pandavro as pdx
3
4rs = pdx.from_avro('user.avro')
5df = pd.DataFrame.from_records(rs)
6df.to_parquet('user.parquet')执行代码只须 3 行。代码中虽未显式导入 pyarrow, 但内部会用到,所以必须安装 pyarrow
链接:
永久链接 https://yanbin.blog/python-convert-avro-to-parquet/, 来自 隔叶黄莺 Yanbin's Blog
[版权声明]
本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。