是否可以DataFrame
直接将火花保存到Hive?
我尝试过转换DataFrame
为Rdd
,然后另存为文本文件,然后在配置单元中加载。但我想知道我是否可以直接保存dataframe
到蜂巢
Answers:
您可以创建一个内存中临时表,然后使用sqlContext将它们存储在配置单元表中。
假设您的数据框是myDf。您可以使用创建一个临时表,
myDf.createOrReplaceTempView("mytempTable")
然后,您可以使用简单的hive语句创建表并从临时表中转储数据。
sqlContext.sql("create table mytable as select * from mytempTable");
temporary
桌子与hive
桌子混合搭配?在执行操作时show tables
,仅包含hive
用于spark 2.3.0
安装的表格
使用DataFrameWriter.saveAsTable
。(df.write.saveAsTable(...)
)参见Spark SQL和DataFrame指南。
df.write().saveAsTable(tableName)
还会将流数据写入表吗?
我没有df.write.saveAsTable(...)
在Spark 2.0文档中看到过时的内容。它在Amazon EMR上为我们工作。我们完全能够将S3中的数据读取到数据帧中,对其进行处理,根据结果创建表并使用MicroStrategy对其进行读取。Vinays的回答也起作用了。
您需要拥有/创建一个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为Append / Ignore / Overwrite / ErrorIfExists
我在此处添加了Spark文档中HiveContext的定义,
除了基本的SQLContext外,您还可以创建HiveContext,它提供基本SQLContext提供的功能的超集。其他功能包括使用更完整的HiveQL解析器编写查询,访问Hive UDF以及从Hive表读取数据的功能。要使用HiveContext,您不需要已有的Hive设置,并且SQLContext可用的所有数据源仍然可用。HiveContext仅单独打包,以避免在默认的Spark版本中包含所有Hive的依赖项。
在Spark版本1.6.2上,使用“ dbName.tableName”会出现此错误:
org.apache.spark.sql.AnalysisException:临时表不允许指定数据库名称或其他限定符。如果表名中包含点(。),请在表名中加上反引号()。
df.write().mode...
需要更改为df.write.mode...
保存到Hive只是使用write()
SQLContext的方法即可:
df.write.saveAsTable(tableName)
从Spark 2.2:使用DataSet代替DataFrame。
From Spark 2.2: use DataSet instead DataFrame.
抱歉,帖子发到很晚,但我没有找到答案。
df.write().saveAsTable
将抛出AnalysisException
并且与HIVE表不兼容。
存储DFdf.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)
当然,DF中的最后一个列将是分区列,因此相应地创建HIVE表!
如果有效,请发表评论!或不。
-更新-
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版本,用于从实木复合地板文件创建Hive表。您可能已经使用推断的架构生成了Parquet文件,现在想将定义推送到Hive元存储。您还可以将定义推送到AWS Glue或AWS Athena等系统,而不仅仅是推送到Hive Metastore。在这里,我使用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
如果您要从数据框创建配置单元表(不存在)(有时无法使用创建
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
数据库中创建。
您可以像这样使用Hortonworks spark-llap库
import com.hortonworks.hwc.HiveWarehouseSession
df.write
.format(HiveWarehouseSession.HIVE_WAREHOUSE_CONNECTOR)
.mode("append")
.option("table", "myDatabase.myTable")
.save()