如何将嵌套大小写 class 转换为 UDTValue 类型
How to convert nested case class into UDTValue type
我正在努力使用自定义案例 类 使用 Spark (1.4.0) 写入 Cassandra (2.1.6)。到目前为止,我已经通过使用 DataStax spark-cassandra-connector 1.4.0-M1
和以下案例 类:
进行了尝试
case class Event(event_id: String, event_name: String, event_url: String, time: Option[Long])
[...]
case class RsvpResponse(event: Event, group: Group, guests: Long, member: Member, mtime: Long, response: String, rsvp_id: Long, venue: Option[Venue])
为了完成这项工作,我还实现了以下转换器:
implicit object EventToUDTValueConverter extends TypeConverter[UDTValue] {
def targetTypeTag = typeTag[UDTValue]
def convertPF = {
case e: Event => UDTValue.fromMap(toMap(e)) // toMap just transforms the case class into a Map[String, Any]
}
}
TypeConverter.registerConverter(EventToUDTValueConverter)
如果我手动查找转换器,我可以使用它将 Event
的实例转换为 UDTValue
,但是,当使用 sc.saveToCassandra
将 [= 的实例传递给它时18=] 与相关对象,我收到以下错误:
15/06/23 23:56:29 ERROR Executor: Exception in task 1.0 in stage 0.0 (TID 1)
com.datastax.spark.connector.types.TypeConversionException: Cannot convert object Event(EVENT9136830076436652815,First event,http://www.meetup.com/first-event,Some(1435100185774)) of type class model.Event to com.datastax.spark.connector.UDTValue.
at com.datastax.spark.connector.types.TypeConverter$$anonfun$convert.apply(TypeConverter.scala:42)
at com.datastax.spark.connector.types.UserDefinedType$$anon$$anonfun$convertPF.applyOrElse(UserDefinedType.scala:33)
at com.datastax.spark.connector.types.TypeConverter$class.convert(TypeConverter.scala:40)
at com.datastax.spark.connector.types.UserDefinedType$$anon.convert(UserDefinedType.scala:31)
at com.datastax.spark.connector.writer.DefaultRowWriter$$anonfun$readColumnValues.apply(DefaultRowWriter.scala:46)
at com.datastax.spark.connector.writer.DefaultRowWriter$$anonfun$readColumnValues.apply(DefaultRowWriter.scala:43)
由于连接器库在内部处理 UDTValue
的方式,我的转换器似乎从未被调用过。但是,上述解决方案确实适用于从 Cassandra 表(包括用户定义的类型)读取数据。基于 connector docs,我还直接用 com.datastax.spark.connector.UDTValue
类型替换了我的嵌套案例 类,然后修复了所描述的问题,但中断了读取数据。我无法想象我打算定义 2 个单独的模型来读取和写入数据。还是我在这里遗漏了一些明显的东西?
从1.3版本开始,无需使用自定义类型转换器来加载和保存嵌套的UDT。只需使用 case 类 对所有内容进行建模并遵守字段命名约定,你应该没问题。
我正在努力使用自定义案例 类 使用 Spark (1.4.0) 写入 Cassandra (2.1.6)。到目前为止,我已经通过使用 DataStax spark-cassandra-connector 1.4.0-M1
和以下案例 类:
case class Event(event_id: String, event_name: String, event_url: String, time: Option[Long])
[...]
case class RsvpResponse(event: Event, group: Group, guests: Long, member: Member, mtime: Long, response: String, rsvp_id: Long, venue: Option[Venue])
为了完成这项工作,我还实现了以下转换器:
implicit object EventToUDTValueConverter extends TypeConverter[UDTValue] {
def targetTypeTag = typeTag[UDTValue]
def convertPF = {
case e: Event => UDTValue.fromMap(toMap(e)) // toMap just transforms the case class into a Map[String, Any]
}
}
TypeConverter.registerConverter(EventToUDTValueConverter)
如果我手动查找转换器,我可以使用它将 Event
的实例转换为 UDTValue
,但是,当使用 sc.saveToCassandra
将 [= 的实例传递给它时18=] 与相关对象,我收到以下错误:
15/06/23 23:56:29 ERROR Executor: Exception in task 1.0 in stage 0.0 (TID 1)
com.datastax.spark.connector.types.TypeConversionException: Cannot convert object Event(EVENT9136830076436652815,First event,http://www.meetup.com/first-event,Some(1435100185774)) of type class model.Event to com.datastax.spark.connector.UDTValue.
at com.datastax.spark.connector.types.TypeConverter$$anonfun$convert.apply(TypeConverter.scala:42)
at com.datastax.spark.connector.types.UserDefinedType$$anon$$anonfun$convertPF.applyOrElse(UserDefinedType.scala:33)
at com.datastax.spark.connector.types.TypeConverter$class.convert(TypeConverter.scala:40)
at com.datastax.spark.connector.types.UserDefinedType$$anon.convert(UserDefinedType.scala:31)
at com.datastax.spark.connector.writer.DefaultRowWriter$$anonfun$readColumnValues.apply(DefaultRowWriter.scala:46)
at com.datastax.spark.connector.writer.DefaultRowWriter$$anonfun$readColumnValues.apply(DefaultRowWriter.scala:43)
由于连接器库在内部处理 UDTValue
的方式,我的转换器似乎从未被调用过。但是,上述解决方案确实适用于从 Cassandra 表(包括用户定义的类型)读取数据。基于 connector docs,我还直接用 com.datastax.spark.connector.UDTValue
类型替换了我的嵌套案例 类,然后修复了所描述的问题,但中断了读取数据。我无法想象我打算定义 2 个单独的模型来读取和写入数据。还是我在这里遗漏了一些明显的东西?
从1.3版本开始,无需使用自定义类型转换器来加载和保存嵌套的UDT。只需使用 case 类 对所有内容进行建模并遵守字段命名约定,你应该没问题。