如何在AWS Glue的Spark数据帧或Spark SQL临时表中包括分区列的值?

时间:2019-12-03 05:39:19

标签: apache-spark pyspark pyspark-sql aws-glue pyspark-dataframes

我正在将python 3,Glue 1.0用于此代码。

我在S3中对数据进行了分区。数据按年,月,日, extra_field_name 列进行分区。

当我将数据加载到数据框中时,我得到的是架构中除分区列以外的所有列。

这是代码和输出

glueContext.create_dynamic_frame_from_options(connection_type = "s3", connection_options = {"paths": path_list, "recurse" : True, 'groupFiles': 'inPartition'}, format = "parquet").toDF().registerTempTable(final_arguement_list["read_table_" + str(i+1)])

path_list变量包含需要加载到数据帧中的路径列表的字符串。 我正在使用以下命令打印架构

glueContext.create_dynamic_frame_from_options(connection_type = "s3", connection_options = {"paths": path_list, "recurse" : True}, format = "parquet").toDF().printSchema()

我在cloudwatch日志中获得的架构不包含任何分区列。 请注意,我已经尝试通过仅通过提供直到年,月,日, extra_field_name 的路径来给出路径来加载数据,但是仍然只获得镶木地板文件本身中存在的那些列。

3 个答案:

答案 0 :(得分:0)

作为一种解决方法,我在数据框中创建了一个重复的列,名为-year_2,month_2,day_2和extra_field_name_2,作为年,月,日和extra_field_name的副本。

在数据提取阶段,我已将数据帧按年,月,日和extra_field_name进行了分区,并将其存储在S3中,该S3在镶木地板文件本身中保留了year_2,month_2,day_2和extra_field_name_2的列值。

在执行数据操作时,我通过以以下方式提供路径列表将数据加载到动态帧中:
['s3://path/to/source/data/year=2018/month=1/day=4/', 's3://path/to/source/data/year=2018/month=1/day=5/', 's3://path/to/source/data/year=2018/month=1/day=6/']

这在动态框架中为我提供了year_2,month_2,day_2和extra_field_name_2,我可以将它们进一步用于数据处理。

答案 1 :(得分:0)

尝试将abc => abc (1) def (123) => def (124) pqr (123) def => pqr (123) def (1) abs (789) (123) => abs (789) (124) 传递给basePath参数:

connection_options

这样,分区发现将发现路径上方的分区。根据{{​​3}},这些选项将传递到Spark SQL数据源。

编辑:鉴于您的实验表明它不起作用,您是否考虑过传递顶层目录并从中筛选感兴趣的日期?阅读器将仅读取相关的Hive分区,因为过滤器被“压入”文件系统。

glueContext.create_dynamic_frame_from_options(
    connection_type = "s3", 
    connection_options = {
        "paths": path_list,
        "recurse" : True,
        "basePath": "s3://path/to/source/data/"
    },
    format = "parquet").toDF().printSchema()

答案 2 :(得分:0)

我还可以执行一个额外的步骤,即使搜寻器在S3上爬网目录,然后将Glue Catalog中的表用作Glue ETL的源。

一旦您在s3:// path / to / source / data /位置上有一个搜寻器,年,月和日将自动被视为分区列。然后,您可以在Glue ETL脚本中尝试以下操作。

data_dyf = glueContext.create_dynamic_frame.from_catalog(
  database = db_name,   
  table_name = tbl_name, 
  push_down_predicate="(year=='2018' and month=='05')"
)

您可以找到更多详细信息here