如何从SQL查询中获取表名?

时间:2018-04-11 23:24:33

标签: scala apache-spark apache-spark-sql

我希望使用Scala从Spark中的sql查询中获取所有表名。

让我们说用户发送一个看起来像这样的SQL查询:

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

我想获得所有表格列表,例如table_1table_2

正则表达式是唯一的选择吗?

7 个答案:

答案 0 :(得分:2)

希望它能帮到你

使用spark sql解析器解析给定查询(spark内部执行相同操作)。您可以从会话状态获取sqlParser。它将给出查询的逻辑计划。迭代查询的逻辑计划&检查它是否是UnresolvedRelation的实例(叶逻辑运算符表示尚未解析的逻辑查询计划中的表引用)&从中获取表格。

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
}

答案 1 :(得分:1)

非常感谢@Swapnil Chougule the answer。这激发了我提供一种在结构化查询中收集所有表的惯用方法。

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

答案 2 :(得分:1)

def __sqlparse2table(self, query):
    '''
    @description: get table name from table
    '''
    plan = self.spark._jsparkSession.sessionState().sqlParser().parsePlan(query)
    plan_string = plan.toString().replace('`.`', '.')
    unr = re.findall(r"UnresolvedRelation `(.*?)`", plan_string)
    cte = re.findall(r"CTE \[(.*?)\]", plan.toString())
    cte = [tt.strip() for tt in cte[0].split(',')] if cte else cte
    schema = set()
    tables = set()
    for table_name in unr:
        if table_name not in cte:
            schema.update([table_name.split('.')[0]])
            tables.update([table_name])

    return schema, tables

答案 3 :(得分:0)

如果要列出数据框中的所有列,请执行

val mydf_cols = df.describe()

答案 4 :(得分:0)

我有一些带有嵌套查询的复杂SQL查询,并在@Jacek Laskowski的答案上进行了迭代

  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
  }

答案 5 :(得分:-1)

由于您需要列出table1和table2中列出的所有列名,因此您可以在hive db中显示db.table_name中的表。

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

您将获得表格中的列列表。

tbl_column1.show

name      
id  
data    

答案 6 :(得分:-2)

unix做了诀窍,grep' INTO \ | FROM \ | JOIN' .sql | sed -r' s /.?(FROM | INTO | JOIN)\ s ?([^] )。 / \ 2 / g' | sort -u

grep'覆盖表' .txt | sed -r' s /。?(覆盖表)\ s?([^] )。 / \ 2 / g' | sort -u