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.
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(...)
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").
J'ai également fait face à la même chose, mais en utilisant les astuces suivantes, j'ai résolu.
Lorsque nous faisons une table en tant que partitionnée, la colonne partitionnée devient sensible à la casse.
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)
}
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")
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