我正在使用spark 1.6,我的目标是创建外部hive表,就像我在hive脚本中所做的那样。为此,我首先阅读分区的avro文件并获取此文件的架构。现在我停在这里,我不知道如何将这个架构应用到我的创建表。我用scala。需要帮助的人。
答案 0 :(得分:4)
最后,我以老式的方式自己做。借助以下代码:
val rawSchema = sqlContext.read.avro("Path").schema
val schemaString = rawSchema.fields.map(field => field.name.replaceAll("""^_""", "").concat(" ").concat(field.dataType.typeName match {
case "integer" => "int"
case smt => smt
})).mkString(",\n")
val ddl =
s"""
|Create external table $tablename ($schemaString) \n
|partitioned by (y int, m int, d int, hh int, mm int) \n
|Stored As Avro \n
|-- inputformat 'org.apache.hadoop.hive.ql.io.avro.AvroContainerInputFormat' \n
| -- outputformat 'org.apache.hadoop.hive.ql.io.avro.AvroContainerOutputFormat' \n
| Location 'hdfs://$path'
""".stripMargin
注意,任何列名都不能以_
开头,而hive无法解析integer
。我想说这种方式不灵活但是有效。如果有人有更好的想法,请发表评论。
答案 1 :(得分:1)
我没有看到自动推断外部表架构的方法。所以我为字符串类型创建了case。您可以为数据类型添加大小写。但我不确定你有多少列。我道歉,因为这可能不是一个干净的方法。
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.sql.{Row, SaveMode};
import org.apache.spark.sql.types.{StructType,StructField,StringType};
val hiveContext = new org.apache.spark.sql.hive.HiveContext(sc)
val results = hiveContext.read.format("com.databricks.spark.avro").load("people.avro")
val schema = results.schema.map( x => x.name.concat(" ").concat( x.dataType.toString() match { case "StringType" => "STRING"} ) ).mkString(",")
val hive_sql = "CREATE EXTERNAL TABLE people_and_age (" + schema + ") ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' LOCATION '/user/ravi/people_age'"
hiveContext.sql(hive_sql)
results.saveAsTable("people_age",SaveMode.Overwrite)
hiveContext.sql("select * from people_age").show()
答案 2 :(得分:-1)
请尝试以下代码。
val htctx= new HiveContext(sc)
htctx.sql(create extetnal table tablename schema partitioned by attribute row format serde serde.jar field terminated by value location path)