क्या DataFrame
स्पाइव में सीधे स्पार्क में बचाना संभव है ?
मैंने एक पाठ फ़ाइल के रूप में परिवर्तित DataFrame
करने Rdd
और फिर बचत करने और फिर हाइव में लोड करने की कोशिश की है । लेकिन मैं सोच रहा हूं कि क्या मैं सीधे dataframe
छत्ता बचा सकता हूं
जवाबों:
आप इन-मेमोरी अस्थायी तालिका बना सकते हैं और उन्हें sqlContext का उपयोग करके हाइव तालिका में संग्रहीत कर सकते हैं।
कहते हैं कि आपका डेटा फ़्रेम myDf है। आप एक अस्थायी तालिका बना सकते हैं,
myDf.createOrReplaceTempView("mytempTable")
तब आप तालिका बनाने और अपने अस्थायी तालिका से डेटा को डंप करने के लिए एक साधारण हाइव स्टेटमेंट का उपयोग कर सकते हैं।
sqlContext.sql("create table mytable as select * from mytempTable");
temporary
टेबल के साथ टेबल को कैसे मिला सकते हैं और मैच कर सकते हैं hive
? जब कर रही show tables
है कि यह केवल शामिल hive
मेरी के लिए टेबल spark 2.3.0
स्थापना
का उपयोग करें DataFrameWriter.saveAsTable
। ( df.write.saveAsTable(...)
) स्पार्क एसक्यूएल और डेटाफ्रेम गाइड देखें ।
df.write().saveAsTable(tableName)
तालिका में स्ट्रीमिंग डेटा भी लिखेगा?
मैं df.write.saveAsTable(...)
स्पार्क 2.0 प्रलेखन में पदावनत नहीं देखता । इसने हमारे लिए Amazon EMR पर काम किया है। हम S3 से डेटा को एक डेटाफ्रेम में पढ़ने में सक्षम थे, इसे प्रोसेस करते हैं, परिणाम से एक तालिका बनाते हैं और इसे माइक्रोस्ट्रैटेरी के साथ पढ़ते हैं। हालांकि विनस जवाब ने भी काम किया है।
आपको 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.write().mode...
बदलने की जरूरत हैdf.write.mode...
हाइव को सहेजना 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 से: डेटाफ़्रेम के बजाय डेटासेट का उपयोग करें।
From Spark 2.2: use DataSet instead DataFrame.
पोस्ट पर देर से लिखने के लिए क्षमा करें, लेकिन मुझे कोई स्वीकृत जवाब नहीं मिला।
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
यहाँ पैर्स्क फ़ाइल से हाइव तालिका बनाने के लिए 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);
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)
मेरे मामले में यह ठीक काम करता है:
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
यदि आप डेटाफ़्रेम से हाइव टेबल (जो मौजूद नहीं है) बनाना चाहते हैं (कुछ समय के साथ बनाने में विफल रहता है
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_table
stg
आप इस तरह हॉर्टनवर्क्स स्पार्क-विलाप लाइब्रेरी का उपयोग कर सकते हैं
import com.hortonworks.hwc.HiveWarehouseSession
df.write
.format("com.hortonworks.spark.sql.hive.llap.HiveWarehouseConnector")
.mode("append")
.option("table", "myDatabase.myTable")
.save()