pyspark 来自带有AWS Glue表分区的EMR笔记本的Spark SQL错误

gcxthw6b  于 2023-01-16  发布在  Spark
关注(0)|答案(3)|浏览(147)

我正在EMR笔记本上测试一些pyspark代码,然后部署它,并不断遇到这个奇怪的错误与Spark SQL。我有我所有的表和元数据与AWS Glue目录集成,以便我可以读和写他们通过spark。
代码的第一部分从S3/Glue读取一些数据,执行一些转换等操作,然后将生成的 Dataframe 写入S3/Glue,如下所示:

df.repartition('datekey','coeff')\
    .write\
    .format('parquet')\
    .partitionBy('datekey','coeff')\
    .mode('overwrite')\
    .option("path", S3_PATH)\
    .saveAsTable('hive_tables.my_table')

然后我尝试用Spark SQL访问这个表,但是当我运行像spark.sql('select * from hive_tables.my_table where datekey=20210506').show()这样简单的代码时,它抛出了以下代码:

An error was encountered:
"org.apache.hadoop.hive.metastore.api.InvalidObjectException: Unknown type : 'double' (Service: AWSGlue; Status Code: 400; Error Code: InvalidInputException; Request ID: 43ff3707-a44f-41be-b14a-7b9906d8d8f9; Proxy: null);"
Traceback (most recent call last):
  File "/usr/lib/spark/python/lib/pyspark.zip/pyspark/sql/readwriter.py", line 778, in saveAsTable
    self._jwrite.saveAsTable(name)
  File "/usr/lib/spark/python/lib/py4j-0.10.7-src.zip/py4j/java_gateway.py", line 1257, in __call__
    answer, self.gateway_client, self.target_id, self.name)
  File "/usr/lib/spark/python/lib/pyspark.zip/pyspark/sql/utils.py", line 69, in deco
    raise AnalysisException(s.split(': ', 1)[1], stackTrace)
pyspark.sql.utils.AnalysisException: "org.apache.hadoop.hive.metastore.api.InvalidObjectException: Unknown type : 'double' (Service: AWSGlue; Status Code: 400; Error Code: InvalidInputException; Request ID: 43ff3707-a44f-41be-b14a-7b9906d8d8f9; Proxy: null);"

我了解到这种情况只会在指定datekey分区时发生。例如,下面两个命令都可以正常工作:spark.sql('select * from hive_tables.my_table where coeff=0.5').show()spark.sql('select * from hive_tables.my_table').show()
我已经通过Spark SQL验证了分区的存在以及分区中的数据,datekey查询在AWS Athena中也能正常工作,只是Spark SQL不行。
Glue也可以识别两个分区列:

datekey: int
coeff: double

有什么主意吗?我已经试过所有我能想到的方法了,但就是没有任何意义。

velaa5lx

velaa5lx1#

我在emr 6.3.0(Spark 3.1.1)中遇到了相同的错误。
升级到emr 6.5.0(Spark 3.1.2)后,问题解决。

s5a0g9ez

s5a0g9ez2#

我仍然希望对此有一个直接的解决方案,但目前此变通方案已足够:
我首先直接从S3路径读取表

temp_df = spark.read.parquet(S3_PATH)

这样它就不会使用Glue目录作为元数据。然后我为会话创建一个临时表:

temp_df.createGlobalTempView('my_table')

这允许我使用Spark SQL和global_temp数据库查询它:

spark.sql('select * from global_temp.my_table where datekey=20210506').show()

这很管用

rqenqsqc

rqenqsqc3#

我在一个类似的环境(EMR集群+Spark SQL + AWS Glue目录)中遇到过类似的问题。

select * 
from ufd.core_agg_data
where year <> date_format(current_timestamp, 'yyyy')

这是一个按"year"分区的表,"year"是一个字符串。注意,过滤器中使用了"year"。
我得到了
用户类抛出异常:org.apache.spark.sql.AnalysisException:org.apache.hadoop.hive.metastore.api.InvalidObjectException:未知运算符'!='
然后我将查询"修改"为这个查询,它成功了!

select * 
from ufd.core_agg_data
where year in (select date_format(current_timestamp, 'yyyy'))

相关问题