Hive को सीधे DataFrame कैसे बचाएं?


85

क्या DataFrameस्पाइव में सीधे स्पार्क में बचाना संभव है ?

मैंने एक पाठ फ़ाइल के रूप में परिवर्तित DataFrameकरने Rddऔर फिर बचत करने और फिर हाइव में लोड करने की कोशिश की है । लेकिन मैं सोच रहा हूं कि क्या मैं सीधे dataframeछत्ता बचा सकता हूं

जवाबों:


116

आप इन-मेमोरी अस्थायी तालिका बना सकते हैं और उन्हें sqlContext का उपयोग करके हाइव तालिका में संग्रहीत कर सकते हैं।

कहते हैं कि आपका डेटा फ़्रेम myDf है। आप एक अस्थायी तालिका बना सकते हैं,

myDf.createOrReplaceTempView("mytempTable") 

तब आप तालिका बनाने और अपने अस्थायी तालिका से डेटा को डंप करने के लिए एक साधारण हाइव स्टेटमेंट का उपयोग कर सकते हैं।

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

2
यह मिल गया के आसपास छत त्रुटियों मैं जब चिंगारी 2.0 में write.saveAsTable का उपयोग कर रही थी पढ़ा
ski_squaw

2
हाँ। हम अस्थायी तालिका बनाने से पहले डेटा फ्रेम पर विभाजन का उपयोग कर सकते हैं। @ चंचल
विनय कुमार

1
आप temporaryटेबल के साथ टेबल को कैसे मिला सकते हैं और मैच कर सकते हैं hive? जब कर रही show tablesहै कि यह केवल शामिल hiveमेरी के लिए टेबल spark 2.3.0स्थापना
StephenBoesch

1
यह अस्थायी तालिका आपके हाइव संदर्भ में सहेजी जाएगी और किसी भी तरह से हाइव टेबल से संबंधित नहीं है।
विनय कुमार

1
hi @VinayKumar आप यह क्यों कहते हैं कि "यदि आप saveAsTable का उपयोग कर रहे हैं (यह आपके डेटाफ़्रेम को अधिक पसंद कर रहा है), तो आपको यह सुनिश्चित करना होगा कि आपके पास आपके स्पार्क एप्लिकेशन को पर्याप्त मेमोरी आवंटित हो"। क्या आप इस बिंदु को समझा सकते हैं?
enneppi

27

का उपयोग करें DataFrameWriter.saveAsTable। ( df.write.saveAsTable(...)) स्पार्क एसक्यूएल और डेटाफ्रेम गाइड देखें ।


4
saveAsTable हाइव संगत टेबल नहीं बनाता है। सबसे अच्छा समाधान मुझे विनय कुमार का मिला।
RChat

@ जेसेक: मैंने खुद इस नोट को जोड़ा है, क्योंकि मुझे लगता है कि मेरा जवाब गलत है। मैं इसे हटा दूंगा, सिवाय इसके कि इसे स्वीकार किया जाए। क्या आपको लगता है कि नोट गलत है?
डैनियल डारबोस

हाँ। नोट गलत था और इसलिए मैंने इसे हटा दिया। "कृपया मुझे सही करें अगर मैं गलत हूँ" यहाँ लागू होता है :)
जसक लस्कॉस्की 13

1
क्या यह df.write().saveAsTable(tableName) तालिका में स्ट्रीमिंग डेटा भी लिखेगा?
user1870400

1
नहीं, आप saveAs के साथ स्ट्रीमिंग डेटा को सहेज नहीं सकते हैं। यह भी Api में नहीं है
ब्रायन

20

मैं df.write.saveAsTable(...)स्पार्क 2.0 प्रलेखन में पदावनत नहीं देखता । इसने हमारे लिए Amazon EMR पर काम किया है। हम S3 से डेटा को एक डेटाफ्रेम में पढ़ने में सक्षम थे, इसे प्रोसेस करते हैं, परिणाम से एक तालिका बनाते हैं और इसे माइक्रोस्ट्रैटेरी के साथ पढ़ते हैं। हालांकि विनस जवाब ने भी काम किया है।


5
किसी ने लंबाई और सामग्री के कारण इस उत्तर को निम्न-गुणवत्ता के रूप में चिह्नित किया। सच कहूं तो यह शायद एक टिप्पणी के रूप में बेहतर होता। मुझे लगता है कि यह दो साल से ऊपर है और कुछ लोगों ने इसे मददगार पाया है ताकि चीजों को छोड़ना अच्छा हो?
सेराकफाल्कन

मैं मानता हूं, टिप्पणी बेहतर विकल्प होती। सबक सीखा :-)
एलेक्स

15

आपको HiveContext का होना / बनाना आवश्यक है

import org.apache.spark.sql.hive.HiveContext;

HiveContext sqlContext = new org.apache.spark.sql.hive.HiveContext(sc.sc());

फिर सीधे डेटाफ़्रेम सहेजें या हाइव टेबल के रूप में संग्रहीत करने के लिए कॉलम का चयन करें

df डेटाफ्रेम है

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

या

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

या

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

SaveModes एपेंड / इग्नोर / ओवरराइट / ErrorIfExists हैं

मैंने यहां स्पार्क डॉक्यूमेंटेशन से HiveContext की परिभाषा जोड़ी,

बेसिक SQLContext के अलावा, आप एक HiveContext भी बना सकते हैं, जो बेसिक SQLContext द्वारा प्रदान की गई कार्यक्षमता का एक सुपरसेट प्रदान करता है। अतिरिक्त विशेषताओं में अधिक पूर्ण HiveQL पार्सर का उपयोग करके प्रश्न लिखने की क्षमता, Hive UDFs तक पहुंच और Hive तालिकाओं से डेटा पढ़ने की क्षमता शामिल है। HiveContext का उपयोग करने के लिए, आपके पास मौजूदा Hive सेटअप होने की आवश्यकता नहीं है, और SQLContext के लिए उपलब्ध सभी डेटा स्रोत अभी भी उपलब्ध हैं। HiveContext डिफ़ॉल्ट स्पार्क बिल्ड में हाइव की निर्भरता के सभी सहित से बचने के लिए अलग से पैक किया गया है।


स्पार्क संस्करण 1.6.2 पर, "dbName.tableName" का उपयोग करके यह त्रुटि मिलती है:

org.apache.spark.sql.AnalysisException: निर्दिष्ट डेटाबेस नाम या अन्य क्वालीफायर अस्थायी तालिकाओं के लिए अनुमति नहीं है। यदि तालिका के नाम में डॉट्स (।) है, तो कृपया तालिका का नाम बैकटिक्स () .` के साथ रखें


दूसरी कमान है: 'df.select (df.col ("col1"), df.col ("col2"), df.col ("col3")) .write ()। मोड ("overwrite")। SaveAsTable ( "schemaName.tableName"); ' आवश्यकता है कि चयनित कॉलम जिसे आप पहले से ही अधिलेखित करने का इरादा रखते हैं, तालिका में मौजूद हैं? तो आपके पास मौजूदा तालिका है और आप केवल मौजूदा कॉलम 1,2,3 को अपने df से स्पार्क में नए डेटा के साथ अधिलेखित करते हैं? क्या यह सही है?
डाईहेलस्टे

3
df.write().mode...बदलने की जरूरत हैdf.write.mode...
उपयोगकर्ता 923227

8

हाइव को सहेजना write()आपके SQLContext की विधि का उपयोग करने की बात है :

df.write.saveAsTable(tableName)

Https://spark.apache.org/docs/2.1.0/api/java/org/apache/spark/sql/DataFrameWriter.html#saveAsTable(java.lang.Sring) देखें

स्पार्क 2.2 से: डेटाफ़्रेम के बजाय डेटासेट का उपयोग करें।


मुझे लगता है कि एक त्रुटि है जो बताती है कि नौकरी निरस्त है मैंने निम्न कोड pyspark_df.write.mode ("अधिलेखित") आज़माया। saveAsTable ("InjuryTab2")
Sade

नमस्ते! यही कारण है? From Spark 2.2: use DataSet instead DataFrame.
onofricamila

3

पोस्ट पर देर से लिखने के लिए क्षमा करें, लेकिन मुझे कोई स्वीकृत जवाब नहीं मिला।

df.write().saveAsTableफेंक देंगे AnalysisExceptionऔर HIVE तालिका संगत नहीं है।

DF के रूप में स्टोर df.write().format("hive")करना चाहिए चाल!

हालांकि, अगर वह काम नहीं करता है, तो पिछली टिप्पणियों और उत्तरों से जा रहा है, यह मेरी राय में सबसे अच्छा समाधान है (हालांकि सुझावों के लिए खोलें)।

सबसे अच्छा तरीका यह है कि स्पष्ट रूप से HIVE तालिका (आंशिक तालिका सहित) बनाएं,

def createHiveTable: Unit ={
spark.sql("CREATE TABLE $hive_table_name($fields) " +
  "PARTITIONED BY ($partition_column String) STORED AS $StorageType")
}

अस्थायी तालिका के रूप में DF को बचाएं,

df.createOrReplaceTempView("$tempTableName")

और आंशिक छत्ता तालिका में डालें:

spark.sql("insert into table default.$hive_table_name PARTITION($partition_column) select * from $tempTableName")
spark.sql("select * from default.$hive_table_name").show(1000,false)

Offcourse अंतिम स्तंभ DF में होगा PARTITION स्तंभ तो छत्ता तालिका तदनुसार बनाने!

कृपया टिप्पणी करें अगर यह काम करता है! या नहीं।


--अपडेट करें--

df.write()
  .partitionBy("$partition_column")
  .format("hive")
  .mode(SaveMode.append)
  .saveAsTable($new_table_name_to_be_created_in_hive)  //Table should not exist OR should be a PARTITIONED table in HIVE

1

यहाँ पैर्स्क फ़ाइल से हाइव तालिका बनाने के लिए PySpark संस्करण है। हो सकता है कि आपने अनुमान स्कीमा का उपयोग करके Parquet फाइलें तैयार की हों और अब हाइव मेटास्टोर की परिभाषा को आगे बढ़ाना चाहते हों। आप एडब्ल्यूएस ग्लू या एडब्ल्यूएस एथेना जैसी प्रणाली की परिभाषा को भी धक्का दे सकते हैं, न कि केवल हाइव मेटास्टोर को। यहां मैं स्थायी तालिका को आगे बढ़ाने / बनाने के लिए स्पार्क.एसक्यूएल का उपयोग कर रहा हूं।

   # 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);

1

Hive बाहरी तालिकाओं के लिए मैं 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)

1

मेरे मामले में यह ठीक काम करता है:

from pyspark_llap import HiveWarehouseSession
hive = HiveWarehouseSession.session(spark).build()
hive.setDatabase("DatabaseName")
df = spark.read.format("csv").option("Header",True).load("/user/csvlocation.csv")
df.write.format(HiveWarehouseSession().HIVE_WAREHOUSE_CONNECTOR).option("table",<tablename>).save()

किया हुआ!!

आप डेटा पढ़ सकते हैं, आपको "कर्मचारी" के रूप में दे सकते हैं

hive.executeQuery("select * from Employee").show()

अधिक जानकारी के लिए इस URL का उपयोग करें: https://docs.cloudera.com/HDPDocuments/HDP3/HDP-3.1.5/integrating-hive/content/hive-read-write-operations.html


0

यदि आप डेटाफ़्रेम से हाइव टेबल (जो मौजूद नहीं है) बनाना चाहते हैं (कुछ समय के साथ बनाने में विफल रहता है DataFrameWriter.saveAsTable)। StructType.toDDLएक तार के रूप में कॉलम को सूचीबद्ध करने में मदद करता है।

val df = ...

val schemaStr = df.schema.toDDL # This gives the columns 
spark.sql(s"""create table hive_table ( ${schemaStr})""")

//Now write the dataframe to the table
df.write.saveAsTable("hive_table")

hive_tableडिफ़ॉल्ट स्थान पर बनाया जाएगा क्योंकि हमने कोई डेटाबेस प्रदान नहीं किया था spark.sql()। डेटाबेस में stg.hive_tableबनाने के लिए इस्तेमाल किया जा सकता है ।hive_tablestg


विस्तृत उदाहरण यहां पाया गया: stackoverflow.com/a/56833395/1592191
mrsrinivas

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.