2015-12-15 4 views
2

Я пытаюсь сохранить scala Enumeration в Cassandra, используя его представление Int, но всегда получаю com.datastax.spark.connector.types.TypeConversionException. Интересно, является ли класс Enumeration особым случаем, или я делаю что-то неправильно.Хранить Enum в Cassandra как Integer, используя Spark Cassandra Connector

Редактировать (2015-12-16). Позвольте мне попытаться распространить мой вопрос на фрагмент кода, поэтому я, вероятно, могу лучше передать идею.

import org.apache.spark.{SparkConf, SparkContext} 

import com.datastax.spark.connector._ 

object WeekDay { 
    sealed abstract class WeekDay(val id: Int) 

    case object MON extends WeekDay(0) 
    case object TUE extends WeekDay(1) 
    case object WED extends WeekDay(2) 
    case object THU extends WeekDay(3) 
    case object FRI extends WeekDay(4) 
    case object SAT extends WeekDay(5) 
    case object SUN extends WeekDay(6) 

    val values = Map(0 -> MON, 1 -> TUE, 2 -> WED, 3 -> THU, 4 -> FRI, 5 -> SAT, 6 -> SUN) 
} 
import WeekDay._ 

object Example { 

    case class MyCassandraRow(id: String, weight: Int, day: WeekDay) 

    def main (args: Array[String]) { 
    val conf = new SparkConf() 
     .setAppName("cassandra-connector-example") 
     .set("spark.serializer", "org.apache.spark.serializer.KryoSerializer") 
     .set("spark.cassandra.connection.host", "127.0.0.1") 
     .setMaster("local[*]") 
    val sc = new SparkContext(conf) 

    val data = sc.parallelize(
     Seq(
     MyCassandraRow("identifier1", 10, MON), 
     MyCassandraRow("identifier2", 20, FRI), 
     MyCassandraRow("identifier3", 1, SUN) 
    ) 
    ) 

    data.saveToCassandra("db", "custom_data") 
    } 
} 

Этот код работает нормально, если я создаю мой custom_data таблицу с помощью текстового поля «день», но терпит неудачу, если я изложу, как INT со следующим StackTrace:

com.datastax.spark.connector.types.TypeConversionException: Cannot convert object FRI of type class WeekDay$FRI$ to java.lang.Integer. 
at com.datastax.spark.connector.types.TypeConverter$$anonfun$convert$1.apply(TypeConverter.scala:42) 
at com.datastax.spark.connector.types.TypeConverter$$anonfun$convert$1.apply(TypeConverter.scala:40) 
at scala.PartialFunction$AndThen.applyOrElse(PartialFunction.scala:185) 

Итак, я попытался реализовать TypeConverter, как описано в https://github.com/datastax/spark-cassandra-connector/blob/master/doc/6_advanced_mapper.md следующим образом:

implicit object IntToWeekDayConverter extends TypeConverter[WeekDay] { 
    def targetTypeTag = typeTag[WeekDay] 
    def convertPF = { 
    case i: Int => values.getOrElse(i, MON) 
    } 
} 

implicit object WeekDayToIntConverter extends TypeConverter[Int] { 
    def targetTypeTag = typeTag[Int] 
    def convertPF = { 
    case d: WeekDay => d.id 
    } 
} 

Но я все еще получаю ту же ошибку.

Я опубликовал весь SCALA файл здесь: https://gist.github.com/davideanastasia/b0bef569b4b7dec66c3f#file-cassandraenum-scala

ответ

1

Там нет автоматического конвертера из Enum -> Integer в Спарке Cassandra Connector. Я бы просто сопоставил этот столбец с .id, чтобы получить целочисленное представление.

object WeekDay extends Enumeration { 
    type WeekDay = Value 
    val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value 
} 
import WeekDay._ 
val meetingDays = Seq(WeekDay.Mon, WeekDay.Wed) 
//meetingDays: Seq[WeekDay.Value] = List(Mon, Wed) 
meetingDays.map(_.id) 
//Seq[Int] = List(0, 2) 
+0

Тогда мне понадобится временный класс для конвертации из Кассандры и из Кассандры в классы моего дела. Я думал, что могу использовать TypeConverter в разъеме Spark Cassandra, чтобы сделать тяжелый подъем для меня. Спасибо за ваш ответ в любом случае, я расширил свой вопрос, поэтому, возможно, контекст немного более ясен. – davideanastasia

+1

Вы пробовали конвертировать в java.lang.Integer вместо scala один – RussS

+0

Да, это работает! После этого мне пришлось изменить несколько второстепенных вещей, но это заставило его работать. Если вы нашли время, чтобы написать полный ответ, я буду его продвигать. – davideanastasia