Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 如何将数据帧直接保存到配置单元?_Scala_Apache Spark_Hive_Apache Spark Sql - Fatal编程技术网

Scala 如何将数据帧直接保存到配置单元?

Scala 如何将数据帧直接保存到配置单元?,scala,apache-spark,hive,apache-spark-sql,Scala,Apache Spark,Hive,Apache Spark Sql,是否可以将spark中的数据帧直接保存到Hive 我尝试过将DataFrame转换为Rdd,然后保存为文本文件,然后加载到配置单元中。但我想知道是否可以直接将数据帧保存到hive中使用。(df.write.saveAsTable(…))请参阅。您可以创建内存中的临时表,并使用sqlContext将其存储在配置单元表中 假设您的数据帧是myDf。可以使用创建一个临时表 myDf.createOrReplaceTempView("mytempTable") 然后,您可以使用一个简单的配置单元语句

是否可以将spark中的数据帧直接保存到Hive


我尝试过将
DataFrame
转换为
Rdd
,然后保存为文本文件,然后加载到配置单元中。但我想知道是否可以直接将数据帧保存到hive中使用。(
df.write.saveAsTable(…)
)请参阅。

您可以创建内存中的临时表,并使用sqlContext将其存储在配置单元表中

假设您的数据帧是myDf。可以使用创建一个临时表

myDf.createOrReplaceTempView("mytempTable") 
然后,您可以使用一个简单的配置单元语句来创建表并从临时表中转储数据

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

您需要拥有/创建HiveContext

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

HiveContext sqlContext = new org.apache.spark.sql.hive.HiveContext(sc.sc());
然后直接保存dataframe或选择要存储为配置单元表的列

df是数据帧

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

保存模式为Append/Ignore/Overwrite/ErrorIfExists

我在这里添加了Spark文档中对HiveContext的定义

除了基本SQLContext之外,还可以创建HiveContext,它提供基本SQLContext提供的功能的超集。其他功能包括使用更完整的HiveQL解析器编写查询的能力、对配置单元UDF的访问以及从配置单元表读取数据的能力。要使用HiveContext,不需要现有的配置单元设置,SQLContext可用的所有数据源仍然可用。HiveContext仅单独打包,以避免在默认Spark构建中包含所有配置单元的依赖项


在Spark版本1.6.2上,使用“dbName.tableName”会出现以下错误:

org.apache.spark.sql.AnalysisException:不允许为临时表指定数据库名称或其他限定符。如果表名中有点(.),请用反勾()引用表名`


在Spark 2.0文档中,我没有看到
df.write.saveAsTable(…)
被弃用。它在Amazon EMR上为我们发挥了作用。我们完全能够将S3中的数据读取到数据帧中,对其进行处理,根据结果创建一个表,并使用MicroStrategy进行读取。
Vinays的答案也很有效。

保存到Hive只需使用SQLContext的
write()
方法即可:

df.write.saveAsTable(tableName)


来自Spark 2.2:使用DataSet代替DataFrame。

这里是PySpark版本,用于从拼花文件创建蜂巢表。您可能已经使用推断模式生成了拼花地板文件,现在希望将定义推送到配置单元元存储。您还可以将定义推送到系统,如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);

对于配置单元外部表,我在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()
有关详细信息,请使用以下URL:

如果要从数据帧创建配置单元表(不存在)(有时无法使用
DataFrameWriter.saveAsTable创建)
StructType.toDDL
将有助于以字符串形式列出列


hive\u表
将在默认空间中创建,因为我们在
spark.sql()
中未提供任何数据库
stg.hive_表
可用于在
stg
数据库中创建
hive_表

很抱歉,我写晚了,但我看不到接受的答案

df.write().saveAsTable
将抛出
AnalysisException
,并且与配置单元表不兼容

将DF存储为
DF.write().format(“hive”)
应该可以做到这一点

然而,如果这不起作用,那么按照前面的评论和答案来看,这是我认为最好的解决方案(尽管可以接受建议)

最好的方法是显式创建配置单元表(包括分区表)

将DF另存为临时表

df.createOrReplaceTempView($tentableName”)

并插入到分区配置单元表中:

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中的最后一列将是分区列,因此相应地创建配置单元表

请评论,如果它的工作!或者不是


--更新--

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
你可以像这样使用Hortonworks图书馆

import com.hortonworks.hwc.HiveWarehouseSession
写
.format(“com.hortonworks.spark.sql.hive.llap.HiveWarehouseConnector”)
.mode(“追加”)
.option(“表”、“myDatabase.myTable”)
.save()

saveAsTable不会创建与配置单元兼容的表。我找到的最好的解决办法是维奈·库马尔。@Jacek:我自己加了这张便条,因为我认为我的答案是错误的。我会删除它,除非它被接受。你认为这张纸条错了吗?是的。这张纸条是错的,所以我把它拿走了。“如果我错了,请纠正我:)这个
df.write().saveAsTable(tableName)
也会将流数据写入表中吗?不,你不能用saveAsTable保存流数据。它甚至不在APIs中。第二个命令是:'df.select(df.col(“col1”)、df.col(“col2”)、df.col(“col3”)。write().mode(“覆盖”).saveAsTable(“schemaName.tableName”);'是否要求表中已存在要覆盖的选定列?那么您有了现有的表,并且只使用spark中df的新数据覆盖现有的列1、2、3?这解释正确吗?
df.write().mode…
需要更改为
df.write.mode…
这解决了我在spark 2.0Yes中使用write.saveAsTable时遇到的拼花地板读取错误。但是,在创建临时表之前,我们可以在数据帧上使用partition by@chhantyal您是如何将
临时
表与
蜂巢
表混合匹配的?执行
show tables
时,它仅包括我的
spark 2.3.0
安装的
hive
表此临时表将保存到您的hive上下文中,不属于hive表
hive.executeQuery("select * from Employee").show()
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")
def createHiveTable: Unit ={
spark.sql("CREATE TABLE $hive_table_name($fields) " +
  "PARTITIONED BY ($partition_column String) STORED AS $StorageType")
}
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.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