使用通配符读取物理分区的数据

xfyts7mz  于 2021-07-13  发布在  Spark
关注(0)|答案(1)|浏览(461)

我在aws s3上有一个持久化的Dataframe,其结构如下:

s3://bucket/df/
|__ date=2020-02-19/
    |__ FILENAME01.json
    |__ FILENAME02.json
    |__ FILENAME03
    |__ ...
|__ date=2020-02-20/
    |__ FILENAME04.json
    |__ FILENAME05
    |__ ...
|__ ...

如果我使用以下语法读取此Dataframe:

df = spark.read.json("s3://bucket/df)"

没有扩展名的文件将成为我的Dataframe的一部分,这是不可取的。所以,我只想考虑 .json 分机。
所以我决定阅读这个Dataframe,过滤带有后缀的文件 *.json . 在实践中,我尝试了以下方法:

df = spark.read.json("s3://bucket/df/date=*/*.json")

这个 spark.read.json 工作,但专栏 date 用于分区的Dataframe不存在。有没有办法只检索与分区文件夹中特定后缀匹配的文件,而不丢失分区列?

jfewjypa

jfewjypa1#

spark只能发现给定输入路径下的分区。但是这里你的路径已经包含了分区 date . 您可以从以下文档中阅读:
从spark 1.6.0开始,默认情况下分区发现只在给定路径下查找分区。对于上面的示例,如果用户通过 path/to/table/gender=male 或者 SparkSession.read.parquet 或者 SparkSession.read.load ,性别将不被视为分区列。如果用户需要指定分区发现开始的基本路径,可以在数据源选项中设置基本路径。例如,当 path/to/table/gender=male 是数据和用户设置为basepath的路径 path/to/table/ ,性别将是一个分区列。
您可以指定 basePath 选项:

df = spark.read.option("basePath", "s3://bucket/df/").json("s3://bucket/df/date=*/*.json")

或者,您可以提取 dateinput_file_name 使用 regexp_extract 功能:

from pyspark.sql import functions as F

df = df.withColumn(
    "date",
    F.regexp_extract(F.input_file_name(), r".*/date=(\d{4}-\d{2}-\d{2})/.*", 1)
)

相关问题