web-dev-qa-db-fra.com

Enregistrer le cadre de données Spark en tant que table partitionnée dynamique dans Hive

J'ai un exemple d'application travaillant pour lire des fichiers csv dans un dataframe. La base de données peut être stockée dans une table Hive au format parquet à l'aide de la méthode df.saveAsTable(tablename,mode)

Le code ci-dessus fonctionne bien, mais j'ai tellement de données pour chaque jour que je veux partitionner dynamiquement la table Hive en fonction de la creationdate (colonne de la table).

existe-t-il un moyen de partitionner dynamiquement le cadre de données et de le stocker dans l’entrepôt Hive? Voulez-vous vous abstenir de coder en dur l'instruction insert en utilisant hivesqlcontext.sql(insert into table partittioin by(date)....).

La question peut être considérée comme une extension de: Comment enregistrer DataFrame directement dans Hive?

toute aide est très appréciée.

23
Chetandalal

Je crois que ça marche quelque chose comme ça:

df est une base de données avec l'année, le mois et d'autres colonnes

df.write.partitionBy('year', 'month').saveAsTable(...)

ou

df.write.partitionBy('year', 'month').insertInto(...)
20
mdurant

J'ai pu écrire sur la table partitionnée Hive à l'aide de df.write().mode(SaveMode.Append).partitionBy("colname").saveAsTable("Table")

Je devais activer les propriétés suivantes pour que cela fonctionne.

 hiveContext.setConf ("Hive.exec.dynamic.partition", "true") 
 hiveContext.setConf ("Hive.exec.dynamic.partition.mode", "sans restriction").
29
Jins George

J'ai également fait face à la même chose, mais en utilisant les astuces suivantes, j'ai résolu.

  1. Lorsque nous faisons une table en tant que partitionnée, la colonne partitionnée devient sensible à la casse.

  2. La colonne partitionnée doit être présente dans DataFrame avec le même nom (sensible à la casse). Code:

    var dbName="your database name"
    var finaltable="your table name"
    
    // First check if table is available or not..
    if (sparkSession.sql("show tables in " + dbName).filter("tableName='" +finaltable + "'").collect().length == 0) {
         //If table is not available then it will create for you..
         println("Table Not Present \n  Creating table " + finaltable)
         sparkSession.sql("use Database_Name")
         sparkSession.sql("SET Hive.exec.dynamic.partition = true")
         sparkSession.sql("SET Hive.exec.dynamic.partition.mode = nonstrict ")
         sparkSession.sql("SET Hive.exec.max.dynamic.partitions.pernode = 400")
         sparkSession.sql("create table " + dbName +"." + finaltable + "(EMP_ID        string,EMP_Name          string,EMP_Address               string,EMP_Salary    bigint)  PARTITIONED BY (EMP_DEP STRING)")
         //Table is created now insert the DataFrame in append Mode
         df.write.mode(SaveMode.Append).insertInto(empDB + "." + finaltable)
    }
    
6
Nilesh Shinde

C'est ce qui fonctionne pour moi. Je règle ces paramètres, puis je mets les données dans des tables partitionnées.

from pyspark.sql import HiveContext
sqlContext = HiveContext(sc)
sqlContext.setConf("Hive.exec.dynamic.partition", "true")
sqlContext.setConf("Hive.exec.dynamic.partition.mode", 
"nonstrict")
0
Shaunak Bangale

Cela a fonctionné pour moi en utilisant python et spark 2.1.0.

Je ne sais pas si c'est la meilleure façon de faire mais ça marche ...

# WRITE DATA INTO A Hive TABLE
import pyspark
from pyspark.sql import SparkSession

spark = SparkSession \
    .builder \
    .master("local[*]") \
    .config("Hive.exec.dynamic.partition", "true") \
    .config("Hive.exec.dynamic.partition.mode", "nonstrict") \
    .enableHiveSupport() \
    .getOrCreate()

### CREATE Hive TABLE (with one row)
spark.sql("""
CREATE TABLE IF NOT EXISTS Hive_df (col1 INT, col2 STRING, partition_bin INT)
USING Hive OPTIONS(fileFormat 'PARQUET')
PARTITIONED BY (partition_bin)
LOCATION 'Hive_df'
""")
spark.sql("""
INSERT INTO Hive_df PARTITION (partition_bin = 0)
VALUES (0, 'init_record')
""")
###

### CREATE NON Hive TABLE (with one row)
spark.sql("""
CREATE TABLE IF NOT EXISTS non_Hive_df (col1 INT, col2 STRING, partition_bin INT)
USING PARQUET
PARTITIONED BY (partition_bin)
LOCATION 'non_Hive_df'
""")
spark.sql("""
INSERT INTO non_Hive_df PARTITION (partition_bin = 0)
VALUES (0, 'init_record')
""")
###

### ATTEMPT DYNAMIC OVERWRITE WITH EACH TABLE
spark.sql("""
INSERT OVERWRITE TABLE Hive_df PARTITION (partition_bin)
VALUES (0, 'new_record', 1)
""")
spark.sql("""
INSERT OVERWRITE TABLE non_Hive_df PARTITION (partition_bin)
VALUES (0, 'new_record', 1)
""")

spark.sql("SELECT * FROM Hive_df").show() # 2 row dynamic overwrite
spark.sql("SELECT * FROM non_Hive_df").show() # 1 row full table overwrite
0
isichei