从多个 parquet 路径创建 Spark SQL 表

Posted

技术标签:

【中文标题】从多个 parquet 路径创建 Spark SQL 表【英文标题】:Create Spark SQL tables from multiple parquet paths 【发布时间】:2018-05-30 23:52:33 【问题描述】:

我使用数据块。我正在尝试创建如下表

`       target_table_name = 'test_table_1'
        spark.sql("""
          drop table if exists %s
          """ % target_table_name)

        spark.sql("""
          create table if not exists 0
          USING org.apache.spark.sql.parquet
          OPTIONS (
          path ("/mnt/sparktables/ds=*/name=xyz/")
          )
          """.format(target_table_name))

尽管使用“*”让我可以灵活地加载不同的文件(模式匹配)并最终创建一个表,但我希望基于两个完全不同的路径创建一个表(没有模式匹配)。

path1 = /mnt/sparktables/ds=*/name=xyz/ path2 = /mnt/sparktables/new_path/name=123fo/

【问题讨论】:

可以先将数据加载到df中:df = spark.read.parquet(path1, path2, path3),然后df.createOrReplaceTempView(target_table_name) df.createOrReplaceTempView(target_table_name):这只会创建一个临时表。但是,我的需要是我想每天更新这张表。 【参考方案1】:

Spark 使用 Hive 元存储来创建这些永久表。这些表本质上是 Hive 中的外部表。

通常您尝试的操作是不可能的,因为 Hive 外部表位置在创建时需要是唯一的。

但是,如果您在 hive 元存储中加入分区策略,您仍然可以实现具有不同位置的 hive 表。

在 hive 元存储中,您可以拥有指向不同位置的分区。

但是,没有现成的方法可以实现这一目标。首先,您需要为数据集指定一个分区键,并从整个数据属于一个分区的第一个位置创建一个表。然后alter table 添加一个新的分区。

示例:

create external table tableName(<schema>) partitioned by ('name') location '/mnt/sparktables/ds=*/name=xyz/'

然后就可以添加分区了

alter table tableName add partition(name='123fo') location '/mnt/sparktables/new_path/name=123fo/'

此过程的替代方法是从 2 个位置创建 2 个数据框,然后将它们组合起来 saveAsaTable

【讨论】:

【参考方案2】:

您可以为两个或多个 parquet 文件分别创建数据框,然后将它们合并(假设它们具有相同的架构)

df1.union(df2)

【讨论】:

以上是关于从多个 parquet 路径创建 Spark SQL 表的主要内容,如果未能解决你的问题,请参考以下文章

使用Spark读写Parquet文件验证Parquet自带表头的性质及NULL值来源Java

使用Spark读写Parquet文件验证Parquet自带表头的性质及NULL值来源Java

使用Spark读写Parquet文件验证Parquet自带表头的性质及NULL值来源Java

为啥聚合的 Spark Parquet 文件比原始文件大?

为啥聚合的 Spark Parquet 文件比原始文件大?

使用 parquet 格式时是不是保存了 DataFrame 架构?