it-swarm.com.de

Wie kann ich DataFrame direkt in Hive speichern?

Ist es möglich, DataFrame in spark direkt in Hive zu speichern.

Ich habe versucht, DataFrame in Rdd zu konvertieren und dann als Textdatei zu speichern und dann in Hive zu laden. Aber ich frage mich, ob ich dataframe direkt in Hive speichern kann

49
Gourav

Wenn Sie saveAsTable verwenden (es ist eher so, als würden Sie Ihren Datenrahmen beibehalten), müssen Sie sicherstellen, dass Sie genügend Speicher für Ihre Spark-Anwendung haben. Bei großen Datensätzen können Sie eine temporäre Tabelle erstellen und sie in der Hive-Tabelle sichern. 

Sie können das in Spark verfügbare sqlContext-Objekt verwenden. 

Nehmen wir an, Ihr Datenrahmen ist myDf. Sie können eine temporäre Tabelle erstellen.

myDf.createOrReplaceTempView("mytempTable") 

Dann können Sie die einfache Hive-Anweisung verwenden, um eine Tabelle zu erstellen und die Daten aus Ihrer temporären Tabelle zu sichern. 

sqlContext.sql("create table mytable as select * from mytempTable");
75
Vinay Kumar

Verwenden Sie DataFrameWriter.saveAsTable . (df.write.saveAsTable(...)) Siehe Spark SQL und DataFrame Guide .

16
Daniel Darabos

In der Spark 2.0-Dokumentation wird df.write.saveAsTable(...) nicht als veraltet angezeigt. Es hat für uns bei Amazon EMR gearbeitet. Wir waren in der Lage, Daten aus S3 in einen Datenrahmen einzulesen, zu verarbeiten, eine Tabelle aus dem Ergebnis zu erstellen und sie mit MicroStrategy zu lesen

13
Alex

sie müssen einen HiveContext haben/erstellen 

import org.Apache.spark.sql.Hive.HiveContext;

HiveContext sqlContext = new org.Apache.spark.sql.Hive.HiveContext(sc.sc());

Speichern Sie dann direkt den Datenrahmen oder wählen Sie die Spalten aus, die als Hive-Tabelle gespeichert werden sollen

df ist Dataframe 

df.write().mode("overwrite").saveAsTable("schemaName.tableName");

oder

df.select(df.col("col1"),df.col("col2"), df.col("col3")) .write().mode("overwrite").saveAsTable("schemaName.tableName");

oder

df.write().mode(SaveMode.Overwrite).saveAsTable("dbName.tableName");

SaveModes sind Anhängen/Ignorieren/Überschreiben/ErrorIfExists

Ich habe hier die Definition für HiveContext aus der Spark-Dokumentation hinzugefügt. 

Neben dem Basis-SQLContext können Sie auch einen HiveContext erstellen, der eine Obermenge der Funktionalität des Basis-SQLContext bereitstellt. Zu den zusätzlichen Funktionen gehören das Schreiben von Abfragen mit dem vollständigeren HiveQL-Parser, der Zugriff auf Hive-UDFs und das Lesen von Daten aus Hive-Tabellen. Um einen HiveContext verwenden zu können, benötigen Sie kein vorhandenes Hive-Setup, und alle für einen SQLContext verfügbaren Datenquellen sind weiterhin verfügbar. HiveContext wird nur separat gepackt, um zu vermeiden, dass alle Abhängigkeiten von Hive in den standardmäßigen Spark-Build eingeschlossen werden. 


bei der Spark-Version 1.6.2 führt die Verwendung von "dbName.tableName" zu diesem Fehler:

org.Apache.spark.sql.AnalysisException: Die Angabe des Datenbanknamens oder anderer Qualifikationsmerkmale ist für temporäre Tabellen nicht zulässig. Wenn der Tabellenname Punkte (.) Enthält, geben Sie den Tabellennamen bitte mit Backticks () .` an

11
Anandkumar

Das Speichern in Hive ist nur eine Frage der Verwendung der write()-Methode Ihres SQLContext:

df.write.saveAsTable(tableName)

Siehe https://spark.Apache.org/docs/2.1.0/api/Java/org/Apache/spark/sql/DataFrameWriter.html#saveAsTable(Java.lang.String)

Ab Spark 2.2: Verwenden Sie DataSet statt DataFrame.

3

Hier ist die PySpark-Version zum Erstellen einer Hive-Tabelle aus der Parkettdatei. Möglicherweise haben Sie Parkettdateien mit einem abgeleiteten Schema erstellt und möchten nun die Definition in den Hive-Metastore verschieben. Sie können Definitionen auch auf das System wie AWS Glue oder AWS Athena übertragen und nicht nur in den Hive-Metastore. Hier verwende ich spark.sql, um eine permanente Tabelle zu Push/erstellen.

   # 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

Für externe Hive-Tabellen verwende ich diese Funktion in PySpark:

def save_table(sparkSession, dataframe, database, table_name, save_format="PARQUET"):
    print("Saving result in {}.{}".format(database, table_name))
    output_schema = "," \
        .join(["{} {}".format(x.name.lower(), x.dataType) for x in list(dataframe.schema)]) \
        .replace("StringType", "STRING") \
        .replace("IntegerType", "INT") \
        .replace("DateType", "DATE") \
        .replace("LongType", "INT") \
        .replace("TimestampType", "INT") \
        .replace("BooleanType", "BOOLEAN") \
        .replace("FloatType", "FLOAT")\
        .replace("DoubleType","FLOAT")
    output_schema = re.sub(r'DecimalType[(][0-9]+,[0-9]+[)]', 'FLOAT', output_schema)

    sparkSession.sql("DROP TABLE IF EXISTS {}.{}".format(database, table_name))

    query = "CREATE EXTERNAL TABLE IF NOT EXISTS {}.{} ({}) STORED AS {} LOCATION '/user/Hive/{}/{}'" \
        .format(database, table_name, output_schema, save_format, database, table_name)
    sparkSession.sql(query)
    dataframe.write.insertInto('{}.{}'.format(database, table_name),overwrite = True)
0
Shadowtrooper