8 votes

Comment obtenir les noms des tables à partir d'une requête SQL ?

Je veux récupérer tous les noms de tables d'une requête sql dans Spark en utilisant Scala.

Supposons que l'utilisateur envoie une requête SQL qui se présente comme suit :

select * from table_1 as a left join table_2 as b on a.id=b.id

J'aimerais obtenir la liste de tous les tableaux comme suit table_1 y table_2 .

Les expressions rationnelles sont-elles la seule option ?

11voto

Jacek Laskowski Points 6668

Merci beaucoup @Swapnil Chougule pour la réponse . Cela m'a incité à proposer un moyen idiomatique de rassembler toutes les tables dans une requête structurée.

scala> spark.version
res0: String = 2.3.1

def getTables(query: String): Seq[String] = {
  val logicalPlan = spark.sessionState.sqlParser.parsePlan(query)
  import org.apache.spark.sql.catalyst.analysis.UnresolvedRelation
  logicalPlan.collect { case r: UnresolvedRelation => r.tableName }
}

val query = "select * from table_1 as a left join table_2 as b on a.id=b.id"
scala> getTables(query).foreach(println)
table_1
table_2

8voto

J'espère que cela vous aidera

Analyse la requête donnée en utilisant spark sql parser (spark fait la même chose en interne). Vous pouvez obtenir sqlParser à partir de l'état de la session. Il donnera le plan logique de la requête. Itérer sur le plan logique de la requête et vérifier s'il s'agit d'une instance de UnresolvedRelation (opérateur logique de feuille pour représenter une référence de table dans un plan logique de requête qui n'a pas encore été résolue) et obtenir la table à partir de ce plan.

def getTables(query: String) : Seq[String] ={
    val logical : LogicalPlan = localsparkSession.sessionState.sqlParser.parsePlan(query)
    val tables = scala.collection.mutable.LinkedHashSet.empty[String]
    var i = 0
    while (true) {
      if (logical(i) == null) {
        return tables.toSeq
      } else if (logical(i).isInstanceOf[UnresolvedRelation]) {
        val tableIdentifier = logical(i).asInstanceOf[UnresolvedRelation].tableIdentifier
        tables += tableIdentifier.unquotedString.toLowerCase
      }
      i = i + 1
    }
    tables.toSeq
}

1voto

William Ma Points 1

J'avais des requêtes sql compliquées avec des requêtes imbriquées et j'ai itéré sur la réponse de @Jacek Laskowski pour obtenir ceci

  def getTables(spark: SparkSession, query: String): Seq[String] = {
    val logicalPlan = spark.sessionState.sqlParser.parsePlan(query)
    var tables = new ListBuffer[String]()
    var i: Int = 0

    while (logicalPlan(i) != null) {
      logicalPlan(i) match {
        case t: UnresolvedRelation => tables += t.tableName
        case _ => 
      }
      i += 1
    }

    tables.toList
  }

0voto

Alef Points 1

Si vous voulez lister toutes les colonnes de votre dataframe, voici ce qu'il faut faire

val mydf_cols = df.describe()

-2voto

salmanbw Points 870

Puisque vous avez besoin de lister tous les noms de colonnes figurant dans table1 et table2, vous pouvez afficher les tables dans db.table_name dans votre répertoire de stockage.

val tbl_column1 = sqlContext.sql("show tables in table1");
val tbl_column2 = sqlContext.sql("show tables in table2");

Vous obtiendrez la liste des colonnes dans les deux tableaux.

tbl_column1.show

name      
id  
data

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X