Est-il possible de spécifier le type de la scala de façon dynamique

0

La question

Je suis nouveau dans Spark, Scala, donc désolé pour la question stupide. J'ai donc un certain nombre de tables:

table_a, table_b, ...

et le nombre de types correspondants de ces tables

classe de cas de classA(...), la classe de cas de classB(...), ...

Alors j'ai besoin d'écrire une des méthodes de lire les données à partir de ces tables et créer un dataset:

def getDataFromSource: Dataset[classA] = {
       val df: DataFrame = spark.sql("SELECT * FROM table_a")
       df.as[classA]
}

De même pour d'autres tables et des types. Est-il possible d'échapper à la routine, code - je veux dire personne fucntion pour chaque table et s'en sortir avec un? Par exemple:

def getDataFromSource[T: Encoder](table_name: String): Dataset[T] = {
       val df: DataFrame = spark.sql(s"SELECT * FROM $table_name")
       df.as[T]
}

Puis créer une liste de paires (table_name, type_name):

val tableTypePairs = List(("table_a", classA), ("table_b", classB), ...)

Puis l'appeler en utilisant foreach:

tableTypePairs.foreach(tupl => getDataFromSource[what should I put here?](tupl._1))

Merci à l'avance!

apache-spark scala
2021-11-23 21:17:33
2

La meilleure réponse

2

Quelque chose comme cela devrait fonctionner

def getDataFromSource[T](table_name: String, encoder: Encoder[T]): Dataset[T] =
  spark.sql(s"SELECT * FROM $table_name").as(encoder)

val tableTypePairs = List(
  "table_a" -> implicitly[Encoder[classA]],
  "table_b" -> implicitly[Encoder[classB]]
)

tableTypePairs.foreach {
  case (table, enc) =>
    getDataFromSource(table, enc)
}

Notez que c'est un cas de rejet d'une valeur qui est un peu une odeur de code. Depuis Encoder est invariant, tableTypePairs n'allez pas avoir l'utilité d'un type, et ni quelque chose comme

tableTypePairs.map {
  case (table, enc) =>
    getDataFromSource(table, enc)
}
2021-11-23 22:09:20
0

Une option est de passer le Class pour la méthode, de cette façon, le type générique T sera déduit:

def getDataFromSource[T: Encoder](table_name: String, clazz: Class[T]): Dataset[T] = {
       val df: DataFrame = spark.sql(s"SELECT * FROM $table_name")
       df.as[T]
}

tableTypePairs.foreach { case (table name, clazz) => getDataFromSource(tableName, clazz) }

Mais alors je ne suis pas sûr de la façon dont vous serez en mesure d'exploiter cette liste de Dataset sans .asInstanceOf.

2021-11-23 22:02:48

Dans d'autres langues

Cette page est dans d'autres langues

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................