【问题标题】:Pyspark with AWS Glue join 1-N relation into a JSON arrayPyspark 与 AWS Glue 将 1-N 关系加入 JSON 数组
【发布时间】:2020-02-14 03:33:26
【问题描述】:

不知道如何在 AWS Glue 上加入 1-N 关系并导出 JSON 文件,例如:

{"id": 123, "name": "John Doe", "profiles": [ {"id": 1111, "channel": "twitter"}, {"id": 2222, "channel": "twitter"}, {"id": 3333, "channel": "instagram"} ]}
{"id": 345, "name": "Test", "profiles": []}

应使用其他表创建配置文件 JSON 数组。我也想添加频道栏。

我在 AWS Glue 数据目录上的 3 个表是:

person_json

{"id": 123,"nanme": "John Doe"}
{"id": 345,"nanme": "Test"}

instagram_json

{"id": 3333, "person_id": 123}
{"id": 3333, "person_id": null}

twitter_json

{"id": 1111, "person_id": 123}
{"id": 2222, "person_id": 123}

这是我目前的脚本:

import sys
from awsglue.transforms import *
from awsglue.utils import getResolvedOptions
from pyspark.context import SparkContext
from pyspark.sql.functions import lit
from awsglue.context import GlueContext
from awsglue.job import Job

glueContext = GlueContext(SparkContext.getOrCreate())

# catalog: database and table names
db_name = "test_database"
tbl_person = "person_json"
tbl_instagram = "instagram_json"
tbl_twitter = "twitter_json"

# Create dynamic frames from the source tables
person = glueContext.create_dynamic_frame.from_catalog(database=db_name, table_name=tbl_person)
instagram = glueContext.create_dynamic_frame.from_catalog(database=db_name, table_name=tbl_instagram)
twitter = glueContext.create_dynamic_frame.from_catalog(database=db_name, table_name=tbl_twitter)

# Join the frames
joined_instagram = Join.apply(person, instagram, 'id', 'person_id').drop_fields(['person_id'])
joined_all = Join.apply(joined_instagram, twitter, 'id', 'person_id').drop_fields(['person_id'])

# Writing output to S3
output_s3_path = "s3://xxx/xxx/person.json"
output = joined_all.toDF().repartition(1)
output.write.mode("overwrite").json(output_s3_path)

应如何更改脚本以实现所需的输出?

谢谢

【问题讨论】:

    标签: pyspark aws-glue


    【解决方案1】:
    from pyspark.sql.functions import collect_set, lit, struct
    ...
    instagram = instagram.toDF().withColumn( 'channel', lit('instagram') )
    instagram = instagram.withColumn( 'profile', struct('id', 'channel') )
    twitter = twitter.toDF().withColumn( 'channel', lit('twitter') )
    twitter = twitter.withColumn( 'profile', struct('id', 'channel') )
    
    profiles = instagram.union(twitter)
    profiles = profiles.groupBy('person_id').agg( collect_set('profile').alias('profiles') )
    
    joined_all = person.join(profiles, person.id == profiles.person_id, 'left_outer').drop('channel', 'person_id')
    joined_all.show(n=2, truncate=False)
    
    +---+--------+-----------------------------------------------------+
    |id |name    |profiles                                             |
    +---+--------+-----------------------------------------------------+
    |123|John Doe|[[1111, twitter], [2222, twitter], [3333, instagram]]|
    |345|Test    |null                                                 |
    +---+--------+-----------------------------------------------------+
    

    .show() 不会在配置文件字段中显示结构的完整结构。

    print(joined_all.collect())
    [Row(id=123, name='John Doe', profiles=[Row(id=1111, channel='twitter'), Row(id=2222, channel='twitter'), Row(id=3333, channel='instagram')]), Row(id=345, name='Test', profiles=None)]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-08-25
      • 1970-01-01
      • 2018-03-31
      • 1970-01-01
      • 2018-08-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多