Parquet4s技术问题:如何将列名以蛇形命名法写入Parquet文件
如何在parquet4s中将case类的小驼峰字段名转为蛇形命名写入Parquet
在使用parquet4s写入Parquet文件时,默认会沿用case类中的小驼峰字段名(如myId、myNestedClass),若希望自动将其转换为蛇形命名(如my_id、my_nested_class),无需手动为每个case类编写编码器和Schema定义,可通过自定义命名解析器实现全局统一转换。
解决方案:自定义SchemaNameResolver
parquet4s提供了SchemaNameResolver trait,允许我们自定义字段名的转换逻辑。只需实现一个全局的隐式实例,就能自动将所有case类的小驼峰字段名转为蛇形命名,包括嵌套类的字段。
import com.github.mjakubowski84.parquet4s.{ParquetWriter, Path, SchemaNameResolver} import scala.util.matching.Regex // 实现小驼峰转蛇形的命名解析器 given SchemaNameResolver = SchemaNameResolver { originalName => val camelCaseRegex: Regex = "([a-z])([A-Z])".r camelCaseRegex.replaceAllIn(originalName, m => s"${m.group(1)}_${m.group(2).toLowerCase}") } // 原case类定义无需修改 case class NestedClass( myId: Int, myOther: String ) case class MyDataModel( myId: Long, myNestedClass: NestedClass ) // 写入逻辑保持不变 val record = MyDataModel(myId = 1L, myNestedClass = NestedClass(myId=2, myOther="sth")) val path = Path("<my_path>/file.parquet") ParquetWriter.of[MyDataModel].writeAndClose(path, List(record))
生成的Parquet Schema
执行上述代码后,生成的Parquet Schema会自动变为蛇形命名:
message MyDataModel { required int64 my_id (INTEGER(64,true)); optional group my_nested_class { required int32 my_id (INTEGER(32,true)); optional binary my_other (STRING); } }
方案优势
- 无需手动为每个case类编写
ValueEncoder和TypedSchemaDef,避免重复劳动 - 全局统一配置,所有case类(包括嵌套结构)都会自动应用命名转换
- 逻辑可扩展,若后续需要其他命名规则,只需修改
SchemaNameResolver的实现即可
内容的提问来源于stack exchange,提问作者Erica
相关产品推荐
相关产品推荐

