我希望使用Scala从Spark中的sql查询中获取所有表名。
让我们说用户发送一个看起来像这样的SQL查询:
select * from table_1 as a left join table_2 as b on a.id=b.id
我想获得所有表格列表,例如table_1
和table_2
。
正则表达式是唯一的选择吗?
答案 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