我需要在Spark中创建一个临时表,其名称与不同的输入源相同。以下是一个例子。
val sqlContext = new org.apache.spark.sql.SQLContext(sc)
import sqlContext.implicits._
case class Person(name: String, age: Int)
val hr_dataframe =
sc.textFile("/user/scvappsit/HR.txt").
map(_.split(",")).
map(p => Person(p(0), p(1).trim.toInt)).
toDF()
hr_dataframe.registerTempTable("employee") //<----- employee registered
val manager_dataframe =
sc.textFile("/user/scvappsit/Manager.txt").
map(_.split(",")).
map(p => Person(p(0), p(1).trim.toInt)).
toDF()
manager_dataframe.registerTempTable("employee") //<----- employee registered
val hr_data = sqlContext.sql("SELECT * FROM employee")
现在在上述情况下,如果我执行SELECT * FROM employee
,它将返回经理的数据而不是 HR。
我需要传递临时表的别名,以便它不会覆盖HR数据。以下是一个例子。
hr_dataframe.registerTempTable("employee".alias("hr"))
sqlContext.sql("select * from hr")
答案 0 :(得分:0)
没有为表名提供别名的功能。在我看来,你有3个选择,那是因为我不理解你的要求。因此,基于您的潜在愿望:
您希望将所有数据合并到一个表中:在仍处于RDD状态时合并两个RDD,然后将结果注册为临时表
hr_dataframe.union(manager_dataframe).registerTempTable( “雇员”)
您希望它是2个单独的表:然后您需要调用一个经理,而另一个员工
您希望他们都被称为员工但仍然分开:然后您需要使用不同的架构名称并在“hr.employee”下保存一个表,在另一个表下保存“manager.employee”。您可能需要预先创建这些模式名称。
答案 1 :(得分:0)
你可以使用隐含。如果你添加
implicit def runAlias(string: String):Alias = new Alias
class Alias {def alias(a:String):String = a }
你可以使用
hr_dataframe.registerTempTable("employee".alias("hr"))
sqlContext.sql("select * from hr")
您将看到Manager.txt
的内容。员工表将保持不变,因此此解决方案与直接使用
hr_dataframe.registerTempTable("hr")
如果我们第二个隐含,我们可以向registerTempTable
添加一些逻辑:
case class Person(name: String, age: Int)
import spark.implicits._
val sqlContext = spark.sqlContext
class Alias(var original: String, var al:String = "") {
def alias(a:String):Alias = {
this.al = a
this
}
}
implicit def runAlias(string: String):Alias = new Alias(string)
implicit class DfOp(val df: org.apache.spark.sql.Dataset[org.apache.spark.sql.Row]) {
def registerTempTable(a: Alias): org.apache.spark.sql.Dataset[org.apache.spark.sql.Row] = {
if( sqlContext.tableNames().contains(a.original) ) {
sqlContext.table(a.original).union(df).registerTempTable(a.original)
}
else {
df.registerTempTable(a.original)
}
df.registerTempTable(a.al)
df
}
}
val hr_dataframe = sc.textFile("/tmp/HR.txt").map(_.split(",")).map(p => Person(p(0), p(1).trim.toInt)).toDF()
hr_dataframe.registerTempTable("employee".alias("hr"))
val manager_dataframe = sc.textFile("/tmp/Manager.txt").map(_.split(",")).map(p => Person(p(0), p(1).trim.toInt)).toDF()
manager_dataframe.registerTempTable("employee".alias("mgr"))
sqlContext.sql("select * from employee").show() // prints the contents of both files
sqlContext.sql("select * from hr").show() // prints the content of HR.txt
sqlContext.sql("select * from mgr").show() // prints the context of Manager.txt
第一个隐式只记录原始表名和别名。
然后第二个隐式将采用原始表并检查是否已存在具有此名称的表。如果是这样,它将合并当前正在注册的表与现有表,否则它将只创建一个新表。之后,将使用别名创建第二个表。
在使用各自的别名注册两个表(HR和Manager)后,将有三个表: