Pyspark从日期层次结构存储中读取选定的日期文件

时间:2019-02-12 10:20:49

标签: regex apache-spark pyspark apache-spark-sql amazon-kinesis-firehose

我正在尝试使用Pyspark读取多个CSV文件,数据由Amazon Kinesis Firehose处理,因此它们以以下格式写入。

s3bucket/ 
    YYYY/
        mm/
            dd/
                hh/
                    files.gz
                    files.gz
                    files.gz

我实际上正在使用此代码通过正则表达式阅读一整天(例如2019年1月15日):

data = spark.read.format("s3selectJson").options(compression="GZIP", multiline=True) \
    .load("s3://s3bucket/2019/01/15/*.gz".format(datetime_object.strftime("%Y/%m/%d")))

我的问题是,我如何才能知道我想要的日期来读取多天的数据?有自动的方法还是我应该为需要的日期制作一个正则表达式?

编辑:
我正在寻找的是下面文档中的DataFrameWriter.partitionBy(* cols)方法的反函数
http://spark.apache.org/docs/latest/api/python/pyspark.sql.html?highlight=regex#pyspark.sql.DataFrameWriter

2 个答案:

答案 0 :(得分:1)

我担心,无法做到这一点。

如果您的数据结构如下(带有month =,year = ...),我们将其称为分区。

s3bucket/ 
    year=YYYY/
        month=mm/
            day=dd/
                hour=hh/
                    files.gz
                    files.gz
                    files.gz

您可以轻松加载数据(在某些情况下需要加载特定日期)

data = spark.read.format("s3selectJson").options(compression="GZIP", multiline=True) \
  .load("s3://s3bucket/")

data_days = data.filter("day in (10, 20)")

使用分区,Spark仅加载您特定的日子,而不是整天。

答案 1 :(得分:0)

我没有找到它的函数,但是,这是一种解决方法:

datetime_object = datetime.strptime("2019-01-31", '%Y-%m-%d')
delta_days = 10
base_bucket = "s3://s3bucket/{}/*/*.gz"
bucket_names = []
for date in [datetime_object - timedelta(days=x) for x in range(0, delta_days)]:
    bucket_names.append(base_bucket.format(date.strftime("%Y/%m/%d")))

幸运的是,.load()函数使用一个列表作为源路径的参数,因此我根据所需的日期生成每个路径并将其提供给load函数。

data = spark.read.format("csv").options(compression="GZIP") \
        .load(bucket_names)