amazon-web-services - 嵌套 XML 数据 AWS Glue
问题描述
我们有一些这种格式的数据:
<doc>
<event timestamp="20200529032100">
<row attr="test" id="3">data</row>
<row attr="gfds" id="6">data</row>
<row attr="sadf" id="8">data</row>
</event>
</doc>
我们要提取每一行的数据,但要同时提取时间戳。我们正在尝试使用 AWS ETL 作业和 CSV 作为输出来做到这一点。
我们试图为 添加一个分类器row
,但是我们没有得到时间戳。当我们尝试为 添加分类器时event
,我们得到了时间戳,但是在 etl 作业之后,从行中提取的字段仅显示其中只有一个条目的事件row
。对于具有多个条目的那些,row
生成的 CSV 中只有一行,我们尝试从中提取的字段row
是空的,而不是获得相同数量的 csv 行,因为有row
条目,这是我们想要的。
这是否可以使用 AWS Glue 解决,还是我们必须自己创建?
解决方案
我们遇到了类似的情况,无法仅使用自定义分类器来构建表格。我们编写了一个作业,使用我们指定的模式将 XML 读入数据帧,然后使用 explode 方法将嵌套元素转换为它们自己的行。
请注意,您需要按照https://towardsdatascience.com/use-aws-glue-and-中的说明将 spark_xml jar 添加为您的工作(或开发端点,如果您在笔记本中开发)的依赖 jar或-databricks-spark-xml-to-process-xml-data-21eaef390fda。
您应该在工作中尝试的大致内容:
- 为元素结构定义一个模式,该模式表示您最初将读入数据框中的行。在您的示例中,如果您希望每个事件一行,请为您的事件元素定义一个架构,其中包含行元素作为数组类型。就像是:
mySchema = StructType(
[StructField('_timestamp',LongType(),True),
StructField('row', ArrayType(StructType([StructField('_VALUE', StringType(), True),
StructField('_attr', StringType(), True),
StructField('_id', LongType(), True)]), True), True)])
- 使用架构将 XML 文件读入数据框
spark_df = spark.read.format("xml").options(rowTag="event").options(nullValue="").schema(mySchema).load("s3://bucket/path/to/xml")
- 使用explode 创建一个新的数据框,每行标签一行
row_df = spark_df.withColumn('eachrow', explode(col('row')))
这将为您提供如下所示的数据框:
+--------------+--------------------+-------------+
| _timestamp| row| eachrow|
+--------------+--------------------+-------------+
|20200529032100|[[data,test,3], [...|[data,test,3]|
|20200529032100|[[data,test,3], [...|[data,gfds,6]|
|20200529032100|[[data,test,3], [...|[data,sadf,8]|
+--------------+--------------------+-------------+
- 选择时间戳属性和行属性/值。
final_df = row_df.select(col('_timestamp').alias('timestamp'), col('eachrow._VALUE').alias('row_value')...)
然后,您可以以您需要的任何格式写出数据框。
推荐阅读
- python - 如何使用字典选项编写 Python 方法?
- javascript - ES5 中类似 ES6 的模板 - 当属性名称中有 .' 时不起作用
- c# - 我可以使用接口来定义基本期望吗?
- python - Python 重定向(有延迟)
- java - 来自同一客户端的 HttpURLConnection 客户端和 API 不同的 Header
- css - HTML/CSS:如何避免从父类继承样式(使用带有引导程序的 react-select)
- php - 为什么 php for 循环可以在没有计数器的情况下运行?
- ios - 当 Apple Music 应用程序从设备中移除时,`canOpenURL` 返回 true
- django - django allauth 显示所有错误信息
- php - 无法在laravel中相互连接表