web-dev-qa-db-ja.com

spark)のスキーマを使用してHive外部テーブルを作成します

spark 1.6を使用しており、Hiveスクリプトで行うのと同じように外部Hiveテーブルを作成することを目指しています。これを行うには、最初にパーティション化されたavroファイルを読み込み、このファイルのスキーマを取得します。ここで停止しましたが、このスキーマを作成テーブルに適用する方法がわかりません。scalaを使用しています。助けが必要です。

5
G_cy

最後に、私は昔ながらの方法でそれを自分で作ります。以下のコードの助けを借りて:

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コメント。

5
G_cy

外部テーブルのスキーマを自動的に推測する方法がわかりませんでした。そこで、文字列型のケースを作成しました。データ型に大文字と小文字を追加できます。しかし、列がいくつあるかはわかりません。これはクリーンなアプローチではない可能性があるため、お詫び申し上げます。

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
Ravi