AWS Glue ETL和PySpark以及分区数据:如何从分区创建数据框列

时间:2019-04-30 18:52:03

标签: amazon-web-services amazon-s3 pyspark aws-glue

我在一个S3存储桶中包含了一些看起来像这样的json文件的数据:

s3://bucket1/news/year=2018/month=01/day=01/hour=xx/

day分区包含多个hour=xx分区,一天中的每个小时一个。我对day分区中的文件运行Glue ETL作业,并创建Glue dynamic_frame_from_options。然后,我使用ApplyMapping.apply应用一些映射,该映射的工作原理像一个超级按钮。

但是,我接下来想根据每个文件的分区创建一个包含hour值的新列。我可以使用Spark创建一个带有常量的新列,但是,如何使该列将分区用作源?

df1 = dynamicFrame.toDF().withColumn("update_date", lit("new column value"))

编辑1

AWS上有关如何使用分区数据的文章在创建dynamicFrame之前先使用了Glue搜寻器,然后从Glue目录中创建了dynamicFrame。我需要直接从S3源创建dynamicFrameenter link description here

4 个答案:

答案 0 :(得分:2)

我并没有真正遵循您的需要。如果您已经分区了文件,您是否已经有了一个hour值,或者仅当您使用create_dynamic_frame .from_catalog时才可以得到它吗? 您可以做df1["hour"]df1.select_fields["hour"]吗?

如果您的数据在ts(timestamp in yyyymmddhh format)上进行了分区,则不需要导入任何库,可以在Spark中使用纯python执行此操作。

示例代码。首先,我创建一些将填充我的DataFrame的值。 然后创建一个如下所示的新变量。

df_values = [('2019010120',1),('2019010121',2),('2019010122',3),('2019010123',4)]
df = spark.createDataFrame(df_values,['yyyymmddhh','some_other_values'])
df_new = df.withColumn("hour", df["yyyymmddhh"][9:10])
df_new.show()
+----------+-----------------+----+
|yyyymmddhh|some_other_values|hour|
+----------+-----------------+----+
|2019010120|                1|  20|
|2019010121|                2|  21|
|2019010122|                3|  22|
|2019010123|                4|  23|
+----------+-----------------+----+

答案 1 :(得分:0)

我对AWS Glue并不熟悉,如果给定的链接不适用于您的情况,那么您可以尝试看看以下解决方法是否对您有效:

使用input_file_name获取文件名,然后使用regexp_extract从文件名获取所需的分区列:

from pyspark.sql.functions import input_file_name, regexp_extract

df2 = df1.withColumn("hour", regexp_extract(input_file_name(), "hour=(.+?)/", 1))

答案 2 :(得分:0)

据我了解您的问题,您希望以小时为分区来构建给定日期的数据框。通常,如果您使用Apache Hive样式的分区路径,并且文件具有相同的架构,则使用应该没有问题

ds = glueContext.create_dynamic_frame.from_options(
    's3',
    {'paths': ['s3://bucket1/news/year=2018/month=01/day=01/']},
    'json')

或...

df = spark.read.option("mergeSchema", "true").json('s3://bucket1/news/year=2018/month=01/day=01/')

因此,如果它不起作用,则应检查是否使用Apache Hive样式的分区路径,并且文件具有相同的架构。

您也可以尝试在Glue中使用boto3框架(这可能对您有用):

import boto3
s3 = boto3.resource('s3')

有用的链接:

https://docs.aws.amazon.com/glue/latest/dg/aws-glue-programming-etl-partitions.html

https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html

答案 3 :(得分:0)

  

“ ...... AWS Glue在DynamicFrame中不包括分区列-它仅包含数据。”

我们必须将S3键加载到新列中,并以编程方式对分区进行解码,以将所需的列创建到动态帧/数据帧中。 创建后,我们可以根据需要使用它们。

ps:我已经对实木复合地板文件进行了测试。它不适用于JSON文件。

Reference