我在一个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源创建dynamicFrame
。
enter link description here
答案 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文件。