Scala & Spark: Recycling SQL 语句



我花了相当长的时间编写多个SQL查询,这些查询以前用于获取各种R脚本的数据。这就是它的工作原理

sqlContent = readSQLFile("file1.sql")
sqlContent = setSQLVariables(sqlContent, variables)
results = executeSQL(sqlContent)

线索是,对于某些查询,需要先前查询的结果 - 为什么在数据库本身中创建VIEW并不能解决此问题。有了Spark 2.0我已经找到了一种方法来做到这一点

// create a dataframe using a jdbc connection to the database
val tableDf = spark.read.jdbc(...)
var tempTableName = "TEMP_TABLE" + java.util.UUID.randomUUID.toString.replace("-", "").toUpperCase
var sqlQuery = Source.fromURL(getClass.getResource("/sql/" + sqlFileName)).mkString
sqlQuery = setSQLVariables(sqlQuery, sqlVariables)
sqlQuery = sqlQuery.replace("OLD_TABLE_NAME",tempTableName)
tableDf.createOrReplaceTempView(tempTableName) 
var data = spark.sql(sqlQuery)

但以我的拙见,这是非常繁琐的。此外,更复杂的查询,例如包含子查询分解的查询目前不起作用。有没有更健壮的方法,比如使用 filter($"").select($"") 等将 SQL 代码重新实现到Spark.SQL代码中。

总体目标是获取多个 org.apache.spark.sql.DataFrame,每个查询表示一个以前的 SQL 查询的结果(总是几个 JOINWITH s 等(。因此,n导致n DataFrame的查询。

有没有比提供的两个更好的选择?

设置: Hadoop v.2.7.3 , Spark 2.0.0 , Intelli J IDEA 2016.2 , Scala 2.11.8 , Win7 工作站上的测试集群

目前还

不是特别清楚您的要求是什么,但我认为您是在说您有这样的查询:

SELECT * FROM people LEFT OUTER JOIN places ON ...
SELECT * FROM (SELECT * FROM people LEFT OUTER JOIN places ON ...) WHERE age>20

并且您希望将其声明并有效地执行为

SELECT * FROM people LEFT OUTER JOIN places ON ...
SELECT * FROM <cachedresult> WHERE age>20

为了实现这一点,我将增强输入文件,以便每个sql语句都有一个关联的表名,结果将存储在其中。

例如

PEOPLEPLACEStSELECT * FROM people LEFT OUTER JOIN places ON ...
ADULTS=SELECT * FROM PEOPLEPLACES WHERE age>18

然后在循环中执行,例如

parseSqlFile().foreach({case (name, query) => {
    val data: DataFrame = execute(query)
    data.createOrReplaceTempView(name)
}

请确保按顺序声明查询,以便创建所有必需的表。其他人做更多的解析和按依赖项排序。

在RDMS中,我将这些表称为物化视图。 即对其他数据(如视图(的转换,但缓存结果以供以后重用。

相关内容

  • 没有找到相关文章

最新更新