PySpark:读取镶木地板时如何在分区列中读取

时间:2018-11-28 09:17:48

标签: apache-spark hadoop pyspark apache-spark-sql parquet

我将数据存储在实木复合地板文件和蜂巢表中,该表按年,月,日划分。因此,每个实木复合地板文件都存储在/table_name/year/month/day/文件夹中。

我只想读取某些分区的数据。我有单个分区的路径列表,如下所示:

paths_to_files = ['hdfs://data/table_name/2018/10/29',
                  'hdfs://data/table_name/2018/10/30']

然后尝试执行以下操作:

df = sqlContext.read.format("parquet").load(paths_to_files)

但是,我的数据不包括有关year, month and day的信息,因为这本身并不是数据的一部分,而是将信息存储在文件的路径中。

我可以使用sql上下文和带有某些select语句的send hive查询,并在年,月和日列上的何处从我感兴趣的分区中仅选择数据。但是,我宁愿避免在python中构造SQL查询因为我很懒惰,不喜欢阅读SQL。

我有两个问题:

  1. 在镶木地板文件中不存在有关年,月,日的信息,而仅包含在文件路径中的最佳方式(性能方面)是什么,以读取作为镶木地板存储的数据? (要么使用sqlContext.sql('...')发送配置单元查询,要么使用read.parquet,等等。
  2. 我可以在使用时以某种方式提取分区列吗     我上面概述的方法?

2 个答案:

答案 0 :(得分:1)

读取到Year分区的父目录的直接文件路径应该足以使数据框确定其下的分区。但是,例如,如果没有目录结构/year=2018/month=10,它将不知道如何命名分区。

因此,如果您有Hive,则通过元存储会更好,因为在此命名了分区,Hive存储了有关表的其他有用信息,因此您不必依赖于知道文件的直接路径。磁盘中的Spark代码。

虽然不确定为什么您认为需要读/写SQL。

改用Dataframe API,例如

df = spark.table("table_name")
df_2018 = df.filter(df['year'] == 2018)
df_2018.show() 

答案 1 :(得分:0)

您的数据没有以最适合镶木地板的方式存储,因此您必须一个一个地加载文件并添加日期

或者,您可以将文件移动到适合实木复合地板的目录结构中 (例如... / table / year = 2018 / month = 10 / day = 29 / file.parquet) 那么您可以读取父目录(表)并按年,月和日进行过滤(而spark只会读取相关目录),也可以将它们作为数据框中的属性获取