Hive Pyspark:将数据帧插入到分区配置单元表中

Hive Pyspark:将数据帧插入到分区配置单元表中,hive,pyspark,hive-partitions,Hive,Pyspark,Hive Partitions,如果我在这里说的很简单,我很抱歉,但是我需要一些Pyspark帮助来尝试动态覆盖配置单元表中的分区。表格被大大简化了,但我正在努力解决的问题(我希望)是清楚的。我是PySpark的新手,已经在StackOverflow中搜索了足够多的时间,终于创建了一个帐户并询问。。。!提前谢谢 我有一个巨大的分区配置单元表(HIVETABLE_TRX),它是从数据帧(TRX)构建的。我将更多数据提取为数据帧(trxup),并希望适当地附加或覆盖HIVETABLE_TRX中的相关分区 Dataframe (tr

如果我在这里说的很简单,我很抱歉,但是我需要一些Pyspark帮助来尝试动态覆盖配置单元表中的分区。表格被大大简化了,但我正在努力解决的问题(我希望)是清楚的。我是PySpark的新手,已经在StackOverflow中搜索了足够多的时间,终于创建了一个帐户并询问。。。!提前谢谢

我有一个巨大的分区配置单元表(HIVETABLE_TRX),它是从数据帧(TRX)构建的。我将更多数据提取为数据帧(trxup),并希望适当地附加或覆盖HIVETABLE_TRX中的相关分区

Dataframe (trx)

+---------------+----------+------+
|PRODUCT_LN_NAME|LOCAL_DATE|   TRX|
+---------------+----------+------+
|          HOTEL|2019-01-01|14298 |
|          HOTEL|2019-01-02|19020 |
|          HOTEL|2019-01-03|18927 |
+---------------+----------+------+

trx.write \
    .partitionBy("PRODUCT_LN_NAME","LOCAL_DATE") \
    .saveAsTable("HIVETABLE_TRX",mode='overwrite')

#Have a look at the partitioned hive table
trxchk = spark.sql("""select * from HIVETABLE_TRX""")
trxchk.show()

+------+---------------+----------+
|   TRX|PRODUCT_LN_NAME|LOCAL_DATE|
+------+---------------+----------+
|14298 |          HOTEL|2019-01-01|
|19020 |          HOTEL|2019-01-02|
|18927 |          HOTEL|2019-01-03|
+------+---------------+----------+
要添加到配置单元表中的数据帧(trxup)有一个重叠行,我要覆盖('HOTEL','2019-01-03'),还有3个增量行要追加

#Have a look at second dataframe (trxup)
+---------------+----------+------+
|PRODUCT_LN_NAME|LOCAL_DATE|   TRX|
+---------------+----------+------+
|         FLIGHT|2019-01-03|14410 |
|          HOTEL|2019-01-03|18927 |
|         FLIGHT|2019-01-04|15430 |
|          HOTEL|2019-01-04|19198 |
+---------------+----------+------+
我尝试将trxup插入HIVETABLE_TRX,如下所示:

trxup.write \
    .insertInto("HIVETABLE_TRX",overwrite=True)
我的理解是,这将覆盖trxup和HIVETABLE_TRX之间共有的一行,并附加其余的一行

#Have a look at HIVETABLE_TRX after the basic insertInto
trxchk2 = spark.sql("""select * from HIVETABLE_TRX""")
trxchk2.show()

+----+---------------+----------+
| TRX|PRODUCT_LN_NAME|LOCAL_DATE|
+----+---------------+----------+
|null|     2019-01-03|    14410 |
|null|     2019-01-03|    18927 |
|null|     2019-01-04|    15430 |
|null|     2019-01-04|    19198 |
+----+---------------+----------+
如您所见,它无法按名称对齐列,并覆盖HIVETABLE_TRX中的所有现有分区

Dataframe (trx)

+---------------+----------+------+
|PRODUCT_LN_NAME|LOCAL_DATE|   TRX|
+---------------+----------+------+
|          HOTEL|2019-01-01|14298 |
|          HOTEL|2019-01-02|19020 |
|          HOTEL|2019-01-03|18927 |
+---------------+----------+------+

trx.write \
    .partitionBy("PRODUCT_LN_NAME","LOCAL_DATE") \
    .saveAsTable("HIVETABLE_TRX",mode='overwrite')

#Have a look at the partitioned hive table
trxchk = spark.sql("""select * from HIVETABLE_TRX""")
trxchk.show()

+------+---------------+----------+
|   TRX|PRODUCT_LN_NAME|LOCAL_DATE|
+------+---------------+----------+
|14298 |          HOTEL|2019-01-01|
|19020 |          HOTEL|2019-01-02|
|18927 |          HOTEL|2019-01-03|
+------+---------------+----------+
因此: 1.如何确保插入项的列对齐? -这是我能想到的最好的方法,虽然成功了,但感觉不应该这样做

colList = spark.sql("""select * from HIVETABLE_TRX""").columns
trxup.selectExpr(colList) \
    .write \
    .insertInto("HIVETABLE_TRX")
  • 我是否可以将第二个df(trxup)插入到分区配置单元表(HIVETABLE_TRX)中,只需添加/覆盖适当的分区
  • 在谷歌、Stackoverflow和灵魂搜索之后,我尝试了其他一些东西:

    为解释器添加了选项

    hive.exec.dynamic.partition = true
    hive.exec.dynamic.partition.mode = nonstrict
    spark.sql.sources.partitionOverwriteMode = dynamic
    
    试图通过插入项上的trxup进行分区

    trxup.write \
        .partitionBy("PRODUCT_LN_NAME","LOCAL_DATE") \
        .insertInto("PROJECT_MERCH.AM_PARTITION_TEST_TRX",overwrite=True)
    
    AnalysisException: u"insertInto() can't be used together with partitionBy(). Partition columns have already be defined for the table. It is not necessary to use partitionBy().;"
    
    从insertInto中删除了overwrite=True,这实际上实现了我在此时的预期(如果不是我想要的话)

    +------+---------------+----------+
    |   TRX|PRODUCT_LN_NAME|LOCAL_DATE|
    +------+---------------+----------+
    |14298 |          HOTEL|2019-01-01|
    |19020 |          HOTEL|2019-01-02|
    |18927 |          HOTEL|2019-01-03|
    |  null|     2019-01-03|    14410 |
    |  null|     2019-01-03|    18927 |
    |  null|     2019-01-04|    15430 |
    |  null|     2019-01-04|    19198 |
    +------+---------------+----------+
    
    我意识到我可以将trxup转换成一个分区的配置单元表(HIVETABLE_trxup),然后将它们合并在一起,但这感觉似乎不是一种最佳的方式——有点违背了分区表的目的,不是吗

    trxjoined = spark.sql("""select * from HIVETABLE_TRX t full outer join HIVETABLE_TRXUP tu on t.SITE_NAME=tu.SITE_NAME and t.LOCAL_DATE=tu.LOCAL_DATE""")
    spark.sql("""drop table if exists HIVETABLE_TRX""")
    spark.sql("""drop table if exists HIVETABLE_TRXUP""")
    trxjoined.write \
        .partitionBy("SITE_NAME","LOCAL_DATE") \
        .saveAsTable("HIVETABLE_TRX",mode='overwrite')
    

    覆盖将清除表中的所有当前数据,并用数据框中的记录填充这些数据。如果您打算使用数据帧trxchk和trxup,那么您可以在Spark中执行转换,然后将最终数据发送到配置单元表。如果我误解了你的问题,请澄清我。@Joby谢谢你的关注。最终目标是HIVETABLE_TRX和数据帧trxup的组合。我不只是在Spark中合并的原因是trx表非常大,所以我一直遇到TTTransport错误,有人建议我只替换/添加相关的分区会有很大帮助。这有意义吗?@joby-修改了帖子,希望能让它更清楚。谢谢覆盖将清除表中的所有当前数据,并用数据框中的记录填充这些数据。如果您打算使用数据帧trxchk和trxup,那么您可以在Spark中执行转换,然后将最终数据发送到配置单元表。如果我误解了你的问题,请澄清我。@Joby谢谢你的关注。最终目标是HIVETABLE_TRX和数据帧trxup的组合。我不只是在Spark中合并的原因是trx表非常大,所以我一直遇到TTTransport错误,有人建议我只替换/添加相关的分区会有很大帮助。这有意义吗?@joby-修改了帖子,希望能让它更清楚。谢谢