![](/img/trans.png)
[英]How to covert Simple Java POJO to avro schema .avsc file and then to autogenerated avro records to finally push it into Kafka topic?
[英]Using avro schema (avsc) for writing avro data to s3 in Java Spark Job
我想使用提供的 Avro 模式而不是 Spark 的自动生成模式以 Avro 格式编写 DataFrame。 如何告诉 Spark 在写入时使用我的自定义架构?
{
"type" : "record",
"name" : "name1",
"namespace" : "com.data"
"fields" : [
{
"name" : "id",
"type" : "string"
},
{
"name" : "count",
"type" : "int"
},
{
"name" : "val_type",
"type" : {
"type" : "enum",
"name" : "ValType"
"symbols" : [ "s1", "s2" ]
}
}
]
}
使用 avroSchema 进行 avro 阅读。 在这一步一切正常。
数据集 d1 = spark.read().option("avroSchema",String.valueOf(inAvroSchema)).format("com.databricks.spark.avro").load("s3_path");
在这里,我对上述数据执行了一些 spark.sql 并存储到 DataFrame。
当我尝试基于 avro 模式将 avro 数据写入 s3 时
DF 数据类型:
root
|-- id: string (nullable = true)
|-- count: integer (nullable = true)
|-- val_type: string (nullable = true)
FinalDF.write().option("avroSchema",String.valueOf(inAvroSchema)).format("com.databricks.spark.avro").mode("overwrite").save("target_s3_path");
我得到了错误:
User class threw exception: org.apache.spark.SparkException: Job aborted.
......
Caused by: org.apache.avro.AvroRuntimeException: **Not a union: "string"**
at org.apache.avro.Schema.getTypes(Schema.java:299)
at
org.apache.spark.sql.avro.AvroSerializer.org$apache$spark$sql$avro$AvroSerializer$$resolveNullableType(AvroSerializer.scala:229)
有什么方法可以使用 avro 模式来编写 avro 数据,或者如果它是正确的方法(使用"option("avroSchema",String.valueOf(inAvroSchema))"
) - 可能是我做错了什么? "forceSchema" option
在我的情况下不起作用。
提前致谢。
我做了一些挖掘,发现了一些有趣的东西,
case class Name1(id: String, count: Int, val_type: String)
val schema = """{
| "type" : "record",
| "name" : "name1",
| "namespace" : "com.data",
| "fields" : [
| {
| "name" : "id",
| "type" : "string"
| },
| {
| "name" : "count",
| "type" : "int"
| },
| {
| "name" : "val_type",
| "type" : {
| "type" : "enum",
| "name" : "ValType",
| "symbols" : [ "s1", "s2" ]
| }
| }
| ]
|}""".stripMargin
val d = Seq(Name1("1",2,"s1"),Name1("1",3,"s2"),Name1("1",4,"s2"),Name1("11",2,"s1")).toDF()
d.write.mode(SaveMode.Overwrite).format("avro").option("avroSchema",schema).save("data/tes2/")
当我使用 spark 2.4.x 执行代码时,上面的代码失败,但是当我使用新的 Spark 3.0.0 运行相同的代码时,代码成功并且数据被成功写入。
val df = spark.read.format("avro").load("data/tes2/")
df.printSchema()
df.show(10)
root
|-- id: string (nullable = true)
|-- count: integer (nullable = true)
|-- val_type: string (nullable = true)
+---+-----+--------+
| id|count|val_type|
+---+-----+--------+
| 11| 2| s1|
| 1| 4| s2|
| 1| 3| s2|
| 1| 2| s1|
+---+-----+--------+
我想最好的办法是升级 spark 版本或更改 avro 模式定义。
您可以使用org.apache.spark:spark-avro
package 并尝试在to_avro
function 上设置avroSchema
选项。 这是文档: https://spark.apache.org/docs/latest/sql-data-sources-avro.html#to_avro-and-from_avro
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.