CSV Format Flink / PyFlink 读写 CSV 的正确姿势(含 Schema 高级配置)

1、依赖引入

Java/Scala 工程需要加 Flink CSV 依赖:

xml 复制代码
<dependency>
  <groupId>org.apache.flink</groupId>
  <artifactId>flink-csv</artifactId>
  <version>2.2.0</version>
</dependency>

PyFlink 用户一般可以直接在作业里使用(前提是集群环境里对应的 jar 能被加载;如果你是在远程集群跑,仍然需要按你前面"依赖管理"章节的方式把 jar 加入 pipeline.jarsenv.add_jars())。

2、Java:快速读取 POJO(自动推导 Schema)

最省事的方式:让 Jackson 根据 POJO 字段推导 CSV schema:

java 复制代码
CsvReaderFormat<SomePojo> csvFormat = CsvReaderFormat.forPojo(SomePojo.class);
FileSource<SomePojo> source =
    FileSource.forRecordStreamFormat(csvFormat, Path.fromLocalFile(...)).build();

注意:CSV 列顺序必须和 POJO 字段顺序一致。必要时加:

java 复制代码
@JsonPropertyOrder({"field1","field2", ...})

否则列对不上会出现解析错位(最常见的"字段都不为空但值都错"的隐性 bug)。

3、Java:高级配置(自定义分隔符、禁用引号等)

需要精细控制时,用 forSchema(...) 自己生成 CsvSchema,例如把分隔符改成 |,并禁用 quote:

java 复制代码
Function<CsvMapper, CsvSchema> schemaGenerator = mapper ->
    mapper.schemaFor(CityPojo.class)
          .withoutQuoteChar()
          .withColumnSeparator('|');

CsvReaderFormat<CityPojo> csvFormat =
    CsvReaderFormat.forSchema(() -> new CsvMapper(), schemaGenerator, TypeInformation.of(CityPojo.class));

FileSource<CityPojo> source =
    FileSource.forRecordStreamFormat(csvFormat, Path.fromLocalFile(...)).build();

对应 CSV:

复制代码
Berlin|52.5167|13.3833|Germany|DE|Berlin|primary|3644826
San Francisco|37.7562|-122.443|United States|US|California||3592294
Beijing|39.905|116.3914|China|CN|Beijing|primary|19433000

更复杂的类型也能做(比如数组列),通过 CsvSchema.ColumnType.ARRAY 并指定数组元素分隔符:

java 复制代码
CsvReaderFormat<ComplexPojo> csvFormat =
    CsvReaderFormat.forSchema(
        CsvSchema.builder()
            .addColumn(new CsvSchema.Column(0, "id", CsvSchema.ColumnType.NUMBER))
            .addColumn(new CsvSchema.Column(4, "array", CsvSchema.ColumnType.ARRAY)
                .withArrayElementSeparator("#"))
            .build(),
        TypeInformation.of(ComplexPojo.class));

4、PyFlink:手动定义 CSV Schema(输出为 Row)

PyFlink 里通常自己建 schema,每一列映射为 Row 字段:

python 复制代码
from pyflink.common.watermark_strategy import WatermarkStrategy
from pyflink.table import DataTypes
from pyflink.datastream import StreamExecutionEnvironment
from pyflink.datastream.connectors.file_system import FileSource
from pyflink.formats.csv import CsvReaderFormat, CsvSchema  # 具体 import 以你环境包结构为准

env = StreamExecutionEnvironment.get_execution_environment()

schema = CsvSchema.builder() \
    .add_number_column('id', number_type=DataTypes.BIGINT()) \
    .add_array_column('array', separator='#', element_type=DataTypes.INT()) \
    .set_column_separator(',') \
    .build()

source = FileSource.for_record_stream_format(
    CsvReaderFormat.for_schema(schema),
    CSV_FILE_PATH
).build()

ds = env.from_source(source, WatermarkStrategy.no_watermarks(), 'csv-source')

# ds 的 record 类型是 Row(具名字段 + 复合类型)
# Types.ROW_NAMED(['id', 'array'], [Types.LONG(), Types.LIST(Types.INT())])

对应 CSV:

复制代码
0,1#2#3
1,
2,1

补一个实战提醒:如果某列可能为空(比如上面的 array),你后续算子处理时要把 None/空数组的分支写好,否则很容易在 map/flat_map 里触发类型错误。

5、PyFlink:写 CSV(Bulk Format)

写 CSV 通常用 CsvBulkWriters 生成 BulkWriterFactory,再配合 FileSink.for_bulk_format(...)

python 复制代码
from pyflink.table import DataTypes
from pyflink.datastream.connectors.file_system import FileSink
from pyflink.formats.csv import CsvBulkWriters, CsvSchema  # 具体 import 以你环境包结构为准

schema = CsvSchema.builder() \
    .add_number_column('id', number_type=DataTypes.BIGINT()) \
    .add_array_column('array', separator='#', element_type=DataTypes.INT()) \
    .set_column_separator(',') \
    .build()

sink = FileSink.for_bulk_format(
    OUTPUT_DIR,
    CsvBulkWriters.for_schema(schema)
).build()

ds.sink_to(sink)

6、运行模式:Batch / Streaming 都可用

CsvReaderFormat 类似 TextLineInputFormat,既可用于批也可用于流(持续监控目录等),具体取决于你用的 Source/RuntimeMode 以及文件系统是否支持持续发现。

相关推荐
前端若水15 分钟前
会话管理:创建、切换、删除对话历史
前端·人工智能·python·react.js
元拓数智18 分钟前
智能分析落地卡壳?先补好「数据关系+语义治理」这层技术基建
大数据·分布式·ai·spark·数据关系·语义治理
涛声依旧-底层原理研究所1 小时前
残差连接与层归一化通俗易懂的详解
人工智能·python·神经网络·transformer
csdn_aspnet1 小时前
Python 算法快闪 LeetCode 编号 70 - 爬楼梯
python·算法·leetcode·职场和发展
TDengine (老段)1 小时前
TDengine Tag 设计哲学与 Schema 变更机制
大数据·数据库·物联网·时序数据库·iot·tdengine·涛思数据
fantasy_arch2 小时前
pytorch人脸匹配模型
人工智能·pytorch·python
熊猫_豆豆2 小时前
广义相对论水星近日点进动完整详细数学推导
python·天体·广义相对论
web3.08889992 小时前
1688 图搜接口(item_search_img / 拍立淘) 接入方法
开发语言·python
sxgzzn2 小时前
新能源场站数智化转型:基于数字孪生与AI的智慧运维管理平台解析
大数据·运维·人工智能
AI算法沐枫2 小时前
深度学习python代码处理科研测序数据
数据结构·人工智能·python·深度学习·决策树·机器学习·线性回归