เป็นไปได้ไหมที่จะบันทึกเป็นDataFrame
ประกายโดยตรงไปยัง Hive?
ฉันได้ลองแปลงDataFrame
เป็นRdd
แล้วบันทึกเป็นไฟล์ข้อความจากนั้นโหลดในกลุ่ม แต่ฉันสงสัยว่าฉันสามารถบันทึกdataframe
ลงในรังได้โดยตรงหรือไม่
เป็นไปได้ไหมที่จะบันทึกเป็นDataFrame
ประกายโดยตรงไปยัง Hive?
ฉันได้ลองแปลงDataFrame
เป็นRdd
แล้วบันทึกเป็นไฟล์ข้อความจากนั้นโหลดในกลุ่ม แต่ฉันสงสัยว่าฉันสามารถบันทึกdataframe
ลงในรังได้โดยตรงหรือไม่
คำตอบ:
คุณสามารถสร้างตารางชั่วคราวในหน่วยความจำและเก็บไว้ในตารางไฮฟ์โดยใช้ sqlContext
สมมติว่า data frame ของคุณคือ 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(...)
) ดูSQL Spark และ DataFrame คู่มือ
df.write().saveAsTable(tableName)
เขียนข้อมูลสตรีมลงในตารางด้วยหรือไม่
ฉันไม่เห็นว่าdf.write.saveAsTable(...)
เลิกใช้แล้วในเอกสาร Spark 2.0 มันได้ผลสำหรับเราใน Amazon EMR เราสามารถอ่านข้อมูลจาก S3 ลงใน dataframe ได้อย่างสมบูรณ์ประมวลผลสร้างตารางจากผลลัพธ์และอ่านด้วย MicroStrategy คำตอบของ Vinays ก็ใช้ได้เช่นกัน
คุณต้องมี / สร้าง HiveContext
import org.apache.spark.sql.hive.HiveContext;
HiveContext sqlContext = new org.apache.spark.sql.hive.HiveContext(sc.sc());
จากนั้นบันทึกดาต้าเฟรมโดยตรงหรือเลือกคอลัมน์เพื่อจัดเก็บเป็นตารางรัง
df คือ dataframe
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 คือ Append / Ignore / Overwrite / ErrorIfExists
ฉันเพิ่มคำจำกัดความสำหรับ HiveContext จาก Spark Documentation ที่นี่
นอกจาก SQLContext พื้นฐานแล้วคุณยังสามารถสร้าง HiveContext ซึ่งจัดเตรียมส่วนเหนือของฟังก์ชันที่จัดเตรียมโดย SQLContext พื้นฐาน คุณสมบัติเพิ่มเติม ได้แก่ ความสามารถในการเขียนแบบสอบถามโดยใช้ตัวแยกวิเคราะห์ HiveQL ที่สมบูรณ์ยิ่งขึ้นการเข้าถึง Hive UDFs และความสามารถในการอ่านข้อมูลจากตาราง Hive ในการใช้ HiveContext คุณไม่จำเป็นต้องมีการตั้งค่า Hive ที่มีอยู่และแหล่งข้อมูลทั้งหมดที่มีอยู่ใน SQLContext จะยังคงมีอยู่ HiveContext ได้รับการบรรจุแยกต่างหากเพื่อหลีกเลี่ยงการรวมการอ้างอิงทั้งหมดของ Hive ใน Spark build เริ่มต้น
บน Spark เวอร์ชัน 1.6.2 โดยใช้ "dbName.tableName" ทำให้เกิดข้อผิดพลาดนี้:
org.apache.spark.sql.AnalysisException: ไม่อนุญาตให้ระบุชื่อฐานข้อมูลหรือคุณสมบัติอื่น ๆ สำหรับตารางชั่วคราว หากชื่อตารางมีจุด (.) อยู่ในนั้นโปรดอ้างอิงชื่อตารางด้วย backticks ()`
df.write().mode...
ต้องเปลี่ยนเป็นdf.write.mode...
การบันทึกไปยังไฮฟ์เป็นเพียงเรื่องของการใช้write()
วิธีการ SQLC ของคุณ
df.write.saveAsTable(tableName)
จาก Spark 2.2: ใช้ DataSet แทน DataFrame
From Spark 2.2: use DataSet instead DataFrame.
ขออภัยที่เขียนโพสต์ช้า แต่ไม่พบคำตอบ
df.write().saveAsTable
จะโยนAnalysisException
และไม่เข้ากันได้กับตาราง HIVE
การจัดเก็บ DF df.write().format("hive")
ควรทำเคล็ดลับ!
อย่างไรก็ตามหากไม่ได้ผลให้แสดงความคิดเห็นและคำตอบก่อนหน้านี้นี่คือทางออกที่ดีที่สุดในความคิดของฉัน (เปิดรับข้อเสนอแนะ)
แนวทางที่ดีที่สุดคือการสร้างตาราง HIVE อย่างชัดเจน (รวมถึงตาราง PARTITIONED)
def createHiveTable: Unit ={
spark.sql("CREATE TABLE $hive_table_name($fields) " +
"PARTITIONED BY ($partition_column String) STORED AS $StorageType")
}
บันทึก DF เป็นตารางอุณหภูมิ
df.createOrReplaceTempView("$tempTableName")
และแทรกลงในตาราง PARTITIONED HIVE:
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)
นำเสนอLAST COLUMNใน DF จะเป็นPARTITION COLUMNดังนั้นให้สร้างตาราง HIVE ตามนั้น!
โปรดแสดงความคิดเห็นว่ามันได้ผล! หรือไม่.
- UPDATE--
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 โดยใช้สคีมาที่สรุปแล้วและตอนนี้ต้องการส่งคำจำกัดความไปยัง Hive metastore คุณยังสามารถส่งคำจำกัดความไปยังระบบเช่น AWS Glue หรือ AWS Athena และไม่ใช่แค่การแพร่กระจายของ Hive เท่านั้น ที่นี่ฉันใช้ spark.sql เพื่อพุช / สร้างตารางถาวร
# 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
คุณสามารถใช้ไลบรารีspark-llap ของ Hortonworks ได้เช่นนี้
import com.hortonworks.hwc.HiveWarehouseSession
df.write
.format("com.hortonworks.spark.sql.hive.llap.HiveWarehouseConnector")
.mode("append")
.option("table", "myDatabase.myTable")
.save()
หากคุณต้องการสร้างตารางไฮฟ์ (ซึ่งไม่มีอยู่) จากดาต้าเฟรม (บางครั้งก็ไม่สามารถสร้างด้วย
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
ฐานข้อมูล