可以将原始SQL字符串转换为DataFrame。但是,是否也有可能采取相反的方法,即为(派生的)星火DataFrame的查询逻辑获取SQL表示?
// Source data
val a = Seq(7, 8, 9, 7, 8, 7).toDF("foo")
// Query using DataFrame functions
val b = a.groupBy($"foo").agg(count("*") as "occurrences").orderBy($"occurrences")
b.show()
// Convert a SQL string into a DataFrame
val sqlString = "SELECT foo, count(*) as occurrences FROM a GROUP BY foo ORDER BY occurrences"
a.createOrReplaceTempView("a")
val c = currentSparkSession.sql(sqlString)
c.show()
// "Convert" a DataFrame into a SQL string
b.toSQLString() // Error: This function does not exist.发布于 2021-04-18 08:40:02
不可能将DataFrame“转换”为string,因为Spark不知道如何编写SQL查询,也不需要这样做。
我发现回忆一下Spark是如何处理Dataframe代码或SQL查询的。这是由星火的催化剂优化器完成的,它经历了四个转换阶段,如下所示:

在第一阶段(分析)中,Spark引擎为SQL或Dataframe查询生成一个抽象语法树(天冬氨酸)。此树是催化剂中的主要数据类型(参见白皮书火花SQL:星火中的关系数据处理中的4.1节),它用于创建逻辑计划,并最终创建物理计划。如果您使用Spark提供的explain API,您将得到这些计划的表示。
虽然在我看来,使用“可以将原始SQL字符串转换为DataFrame”的含义很清楚,但我想这有助于更精确。我们并不是将SQL字符串(因此您自己将该单词的引号)转换为Dataframe,而是应用您的SQL知识,因为这是一种可以由Spark解析以理解您的意图的语法。此外,您不能只键入任何SQL查询,因为在与Catalog进行比较时,这仍然可能在分析阶段失败。因此,SQL字符串只是一个关于Spark如何允许您提供指令的协议。然后解析这个SQL查询,将其转换为AST (如前所述),并在经过其他三个阶段之后,在基于RDD的代码中结束。通过sql API执行这个SQL的结果返回一个Dataframe,而您可以轻松地用df.rdd将它转换成一个RDD。
总的来说,Spark不需要将任何代码,特别是任何Dataframe代码编写到SQL语法中,然后您就可以退出Spark了。AST是内部抽象,Spark不需要首先将Dataframe代码转换为SQL查询,而不是直接将Dataframe代码转换为AST。
发布于 2021-04-15 15:56:57
不是的。没有任何方法可以从dataframe获取SQL查询。您必须自己创建查询,方法是查看所有过滤器,并选择用于创建dataframe的内容。
https://stackoverflow.com/questions/67109924
复制相似问题