it-swarm.com.ru

Как создать таблицу Hive из фрейма данных Spark, используя его схему?

Я хочу создать таблицу Hive, используя схему моего информационного кадра Spark. Как я могу это сделать?

Для фиксированных столбцов я могу использовать:

val CreateTable_query = "Create Table my table(a string, b string, c double)"
sparksession.sql(CreateTable_query) 

Но у меня в столбце данных много столбцов, так есть ли способ автоматически сгенерировать такой запрос?

3
lserlohn

Предполагая, что вы используете Spark 2.1.0 или более позднюю версию, а my_DF - ваш фрейм

//get the schema split as string with comma-separated field-datatype pairs
StructType my_schema = my_DF.schema();
StructField[] fields = my_schema.fields();
String fieldStr = "";
for (StructField f : fields) {
fieldStr += f.name() + " " + f.dataType().typeName() + ",";
}

//drop the table if already created
spark.sql("drop table if exists my_table");
//create the table using the dataframe schema
spark.sql("create table my_table(" + fieldStr.subString(0,fieldStr.length()-1)+
") row format delimited fields terminated by '|' location '/my/hdfs/location'");
    //write the dataframe data to the hdfs location for the created Hive table
    my_DF.write()
    .format("com.databricks.spark.csv")
    .option("delimiter","|")
    .mode("overwrite")
    .save("/my/hdfs/location");

Другой метод, использующий временную таблицу 

my_DF.createOrReplaceTempView("my_temp_table");
spark.sql("drop table if exists my_table");
spark.sql("create table my_table as select * from my_temp_table");
7
somnathchakrabarti

По вашему вопросу, похоже, что вы хотите создать таблицу в Hive, используя схему вашего фрейма данных. Но, как вы говорите, у вас есть много столбцов в этом фрейме данных, поэтому есть два варианта 

  • Во-первых, создать прямую таблицу Hive через фрейм данных.
  • Второе - взять схему этого фрейма данных и создать таблицу в Hive.

Рассмотрим этот код:

package Hive.example

import org.Apache.spark.SparkConf
import org.Apache.spark.SparkContext
import org.Apache.spark.sql.SQLContext
import org.Apache.spark.sql.Row
import org.Apache.spark.sql.SparkSession

object checkDFSchema extends App {
  val cc = new SparkConf;
  val sc = new SparkContext(cc)
  val sparkSession = SparkSession.builder().enableHiveSupport().getOrCreate()
  //First option for creating Hive table through dataframe 
  val DF = sparkSession.sql("select * from salary")
  DF.createOrReplaceTempView("tempTable")
  sparkSession.sql("Create table yourtable as select * form tempTable")
  //Second option for creating Hive table from schema
  val oldDFF = sparkSession.sql("select * from salary")
  //Generate the schema out of dataframe  
  val schema = oldDFF.schema
  //Generate RDD of you data 
  val rowRDD = sc.parallelize(Seq(Row(100, "a", 123)))
  //Creating new DF from data and schema 
  val newDFwithSchema = sparkSession.createDataFrame(rowRDD, schema)
  newDFwithSchema.createOrReplaceTempView("tempTable")
  sparkSession.sql("create table FinalTable AS select * from tempTable")
}
6
Nilesh Shinde

Вот версия PySpark для создания таблицы Hive из файла паркета. Возможно, вы сгенерировали файлы Parquet, используя выведенную схему, и теперь хотите отправить определение в метасчет Hive. Вы также можете отправить определение в систему, например AWS Glue или AWS Athena, а не только в Hive metastore. Здесь я использую spark.sql для Push/создать постоянную таблицу.

 # Location where my parquet files are present.
 df = spark.read.parquet("s3://my-location/data/")

    cols = df.dtypes
    buf = []
    buf.append('CREATE EXTERNAL TABLE test123 (')
    keyanddatatypes =  df.dtypes
    sizeof = len(df.dtypes)
    print ("size----------",sizeof)
    count=1;
    for eachvalue in keyanddatatypes:
        print count,sizeof,eachvalue
        if count == sizeof:
            total = str(eachvalue[0])+str(' ')+str(eachvalue[1])
        else:
            total = str(eachvalue[0]) + str(' ') + str(eachvalue[1]) + str(',')
        buf.append(total)
        count = count + 1

    buf.append(' )')
    buf.append(' STORED as parquet ')
    buf.append("LOCATION")
    buf.append("'")
    buf.append('s3://my-location/data/')
    buf.append("'")
    buf.append("'")
    ##partition by pt
    tabledef = ''.join(buf)

    print "---------print definition ---------"
    print tabledef
    ## create a table using spark.sql. Assuming you are using spark 2.1+
    spark.sql(tabledef);
0
kartik