DataFrame을 Hive에 직접 저장하는 방법은 무엇입니까?


85

DataFrameSpark에서 Hive에 직접 저장할 수 있습니까?

변환 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
예. 그러나 임시 테이블을 생성하기 전에 데이터 프레임에서 partition by를 사용할 수 있습니다. @chhantyal
비나이 쿠마르

1
temporary테이블과 테이블 을 어떻게 혼합하고 일치시킬 수 있었 hive습니까? 수행 할 때 show tables그것을에만 포함 hive내 테이블 spark 2.3.0설치
StephenBoesch

1
이 임시 테이블은 하이브 컨텍스트에 저장되며 어떤 식 으로든 하이브 테이블에 속하지 않습니다.
Vinay Kumar

1
안녕 @VinayKumar 왜 "당신이 saveAsTable을 사용하고 있다면 (데이터 프레임을 유지하는 것과 더 비슷 함), 당신은 당신의 스파크 애플리케이션에 충분한 메모리가 할당되어 있는지 확인해야합니다". 이 점을 설명해 주시겠습니까?
enneppi

27

사용 DataFrameWriter.saveAsTable. ( df.write.saveAsTable(...)) Spark SQL 및 DataFrame 가이드를 참조하십시오 .


4
saveAsTable은 Hive 호환 테이블을 생성하지 않습니다. 내가 찾은 최고의 솔루션은 Vinay Kumar입니다.
RChat

@Jacek : 내 대답이 틀렸다고 생각하기 때문에이 메모를 직접 추가했습니다. 나는 그것을 수락하는 것을 제외하고는 그것을 삭제할 것입니다. 메모가 잘못되었다고 생각하십니까?
Daniel Darabos

예. 메모가 잘못 되었기 때문에 제거했습니다. :) 여기에 적용 대상 "내가 틀렸다면 수정하십시오"
제이 섹 Laskowski에게

1
이것은 df.write().saveAsTable(tableName) 또한 스트리밍 데이터를 테이블에 기록합니까?
user1870400

1
아무 당신은 아니에요 심지어 API의 saveAsTable 데이터를 스트리밍 저장할 수 없습니다
브라이언

20

df.write.saveAsTable(...)Spark 2.0 문서에서 더 이상 사용되지 않는 항목이 표시 되지 않습니다. Amazon EMR에서 우리를 위해 일했습니다. 우리는 S3에서 데이터 프레임으로 데이터를 읽고, 처리하고, 결과에서 테이블을 생성하고, MicroStrategy로 읽을 수있었습니다. Vinays 답변도 작동했습니다.


5
누군가가 길이와 내용으로 인해이 답변의 품질이 낮은 것으로 표시했습니다. 솔직히 말하면 아마도 댓글로 더 좋았을 것입니다. 2 년이 지났는데 어떤 사람들은 도움이 되었으니 그대로 두는 것이 좋을까요?
serakfalcon

동의합니다. 댓글이 더 나은 선택이었을 것입니다. 레슨 :-) 배웠
알렉스

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

SaveMode는 Append / Ignore / Overwrite / ErrorIfExists입니다.

여기에 Spark Documentation의 HiveContext에 대한 정의를 추가했습니다.

기본 SQLContext 외에도 기본 SQLContext에서 제공하는 기능의 상위 집합을 제공하는 HiveContext를 만들 수도 있습니다. 추가 기능에는보다 완전한 HiveQL 파서를 사용하여 쿼리를 작성하는 기능, Hive UDF에 대한 액세스 및 Hive 테이블에서 데이터를 읽는 기능이 포함됩니다. HiveContext를 사용하기 위해 기존 Hive 설정이 필요하지 않으며 SQLContext에 사용 가능한 모든 데이터 소스를 계속 사용할 수 있습니다. HiveContext는 기본 Spark 빌드에 Hive의 모든 종속성을 포함하지 않도록 개별적으로 만 패키징됩니다.


Spark 버전 1.6.2에서 "dbName.tableName"을 사용하면 다음 오류가 발생합니다.

org.apache.spark.sql.AnalysisException : 임시 테이블에는 데이터베이스 이름 또는 기타 규정자를 지정할 수 없습니다. 테이블 이름에 마침표 (.)가있는 경우 백틱 ()으로 테이블 이름을 인용하십시오 .`


두 번째 명령 : 'df.select (df.col ( "col1"), df.col ( "col2"), df.col ( "col3")) .write (). mode ( "overwrite"). saveAsTable ( "schemaName.tableName"); ' 덮어 쓰려는 선택한 열이 이미 테이블에 있어야합니까? 따라서 기존 테이블이 있고 기존 열 1,2,3 만 spark의 df의 새 데이터로 덮어 씁니까? 그게 맞아요?
dieHellste

3
df.write().mode...로 변경해야합니다df.write.mode...
사용자 923,227

8

Hive에 저장하는 것은 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.String) 참조

Spark 2.2에서 : DataFrame 대신 DataSet을 사용합니다.


작업이 중단되었다는 오류가있는 것 같습니다. 다음 코드를 시도했습니다. pyspark_df.write.mode ( "overwrite"). saveAsTable ( "InjuryTab2")
Sade

안녕하세요! 왜 이래? From Spark 2.2: use DataSet instead DataFrame.
onofricamila

3

게시물에 늦게 작성하여 죄송하지만 수락 된 답변이 없습니다.

df.write().saveAsTable던지고 AnalysisExceptionHIVE 테이블과 호환되지 않습니다.

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)

Offcourse 에서 DF 의 LAST COLUMNPARTITION COLUMN이 되므로 이에 따라 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

1

다음은 parquet 파일에서 Hive 테이블을 만드는 PySpark 버전입니다. 추론 된 스키마를 사용하여 Parquet 파일을 생성했으며 이제 정의를 Hive 메타 스토어에 푸시하려고 할 수 있습니다. 정의를 Hive 메타 스토어뿐만 아니라 AWS Glue 또는 AWS Athena와 같은 시스템에 푸시 할 수도 있습니다. 여기에서는 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);

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

0

Hortonworks spark-llap 라이브러리를 다음과 같이 사용할 수 있습니다.

import com.hortonworks.hwc.HiveWarehouseSession

df.write
  .format("com.hortonworks.spark.sql.hive.llap.HiveWarehouseConnector")
  .mode("append")
  .option("table", "myDatabase.myTable")
  .save()
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.