pyspark:读取parquet时如何读取分区列

brqmpdu1  于 2021-06-01  发布在  Hadoop
关注(0)|答案(2)|浏览(825)

我把数据存储在Parquet地板文件和配置单元表中,按年、月、日进行分区。因此,每个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上下文和send-hive查询以及一些select语句,其中的where on the year、month和day列只从我感兴趣的分区中选择数据。但是,我宁愿避免在python中构造sql查询,因为我非常懒惰,不喜欢阅读sql。
我有两个问题:
什么是读取存储为parquet的数据的最佳方式(性能方面),其中有关年、月、日的信息不在parquet文件中,而只包含在文件的路径中(使用发送配置单元查询 sqlContext.sql('...') ,或使用 read.parquet ,... 什么都可以。
在使用上述方法时,我是否可以提取分区列?

lndjwyie

lndjwyie1#

读取到当年父目录分区的直接文件路径应该足以让Dataframe确定它下面有分区。但是,如果没有目录结构,它将不知道如何命名分区 /year=2018/month=10 ,例如。
因此,如果您有hive,那么通过metastore访问会更好,因为分区在那里命名,hive存储关于您的表的额外有用信息,并且您不依赖于从spark代码知道磁盘上文件的直接路径。
不过,不知道为什么需要读/写sql。
改用dataframeapi,例如

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

67up9zun2#

您的数据不是以最适合Parquet的方式存储的,因此您必须逐个加载文件并添加日期
或者,您可以将文件移动到适合parquet的目录结构(例如../table/year=2018/month=10/day=29/file.parquet),然后您可以读取父目录(table)并按年、月和日进行筛选(spark将只读取相关目录),您还可以在Dataframe中将这些作为属性获取

相关问题