spark 1.6を使用しており、Hiveスクリプトで行うのと同じように外部Hiveテーブルを作成することを目指しています。これを行うには、最初にパーティション化されたavroファイルを読み込み、このファイルのスキーマを取得します。ここで停止しましたが、このスキーマを作成テーブルに適用する方法がわかりません。scalaを使用しています。助けが必要です。
最後に、私は昔ながらの方法でそれを自分で作ります。以下のコードの助けを借りて:
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
を解析できないことに注意してください。この方法は柔軟ではありませんが、機能します。誰かがより良いアイデアを得るなら、plzコメント。
外部テーブルのスキーマを自動的に推測する方法がわかりませんでした。そこで、文字列型のケースを作成しました。データ型に大文字と小文字を追加できます。しかし、列がいくつあるかはわかりません。これはクリーンなアプローチではない可能性があるため、お詫び申し上げます。
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()