很抱歉,如果我在这里真的很基础,但是我需要一点Pyspark帮助,以尝试动态覆盖hive表中的分区。表已大大简化,但是(我希望)我正在努力解决的问题很清楚。我是PySpark的新手,已经在StackOverflow上搜索了足够的时间,终于可以创建一个帐户并询问...了!在此先感谢!
我有一个从数据帧(trx)构建的大型分区配置单元表(HIVETABLE_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|
+------+---------------+----------+
要添加到Hive表中的数据帧(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中的所有现有分区。
所以: 1.如何确保insertInto的列对齐? -这是我能想到的最好的方法,尽管成功了,但并不觉得应该这样做...?
colList = spark.sql("""select * from HIVETABLE_TRX""").columns
trxup.selectExpr(colList) \
.write \
.insertInto("HIVETABLE_TRX")
我在Google,Stackoverflow和灵魂搜索之后尝试过的其他方法:
为解释器添加了选项
hive.exec.dynamic.partition = true
hive.exec.dynamic.partition.mode = nonstrict
spark.sql.sources.partitionOverwriteMode = dynamic
试图通过在insertInto上的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),然后将它们合并在一起,但这似乎不是一种最佳方法-破坏了分区表的目的,不是吗?< / p>
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')