如何在Spark SQL中使用分区发现

时间:2018-08-23 06:07:04

标签: apache-spark apache-spark-sql

给出具有镶木地板文件的HDFS中的下一个结构:

    data
    ├── name=Steve
    └── name=Michael

在SparkSQL中,查询如下:

CREATE TABLE test USING parquet OPTIONS (path 'hdfs://namenode:8020/data')

无法正确恢复分区并且未检测到数据:

SELECT * FROM test LIMIT 1

+---+----+
|ID |name|
+---+----+
+---+----+

但是,还有一种替代方法,即在创建表时指定架构,然后再使用恢复分区

执行更改表
CREATE TABLE test2(ID Int, name String) USING parquet OPTIONS (path 'hdfs://namenode:8020/data')

ALTER TABLE test2 RECOVER PARTITIONS

SELECT * FROM test2 LIMIT 1

+----+---------+
| ID |    name |
+----+---------+
|  1 |   Steve |
|  2 | Michael |
+----+---------+

Spark SQL中是否还有其他选择,可以在创建表时不指定模式就仅使用一个查询来使用分区发现?

2 个答案:

答案 0 :(得分:2)

通过spark sql创建表后,例如: 使用镶木地板选项创建表测试(路径“ hdfs:// namenode:8020 / data”)

请记住在使用表之前先对其进行修复: MSCK维修台测试

然后,表的分区将被注册到metastore中。否则,该表将不返回任何结果。如本在线文档所述:https://docs.databricks.com/user-guide/tables.html

答案 1 :(得分:0)

假设使用以下目录结构将人口数据加载到分区表中,其中有两个额外的列,性别和国家作为分区列:

path
└── to
    └── table
        ├── gender=male
        │   ├── ...
        │   │
        │   ├── country=US
        │   │   └── data.parquet
        │   ├── country=CN
        │   │   └── data.parquet
        │   └── ...
        └── gender=female
            ├── ...
            │
            ├── country=US
            │   └── data.parquet
            ├── country=CN
            │   └── data.parquet
            └── ...

通过将路径/目标/表传递到SparkSession.read.parquet或SparkSession.read.load,Spark SQL将自动从路径中提取分区信息。现在,返回的DataFrame的架构变为:

root
|-- name: string (nullable = true)
|-- age: long (nullable = true)
|-- gender: string (nullable = true)
|-- country: string (nullable = true)

如果使用spark.sql,则使用Hive实木复合地板-提供的设置正确,而不是在需要修复的S3上,然后按问题提供spark.sql,只要能够识别分区即可。

例如一个简单的示例(由于某些原因无法格式化):

dfX.write.partitionBy(“ col2”)。format(“ parquet”)。saveAsTable(“ dfX_partitionBy_Table”)

但是在您的问题中,如果不想在这里,那么答案是“否”。