首先说一下,这里解决的问题应用场景:

sparksql处理Hive表数据时,判断加载的是否是分区表,以及分区表的字段有哪些?再进一步限制查询分区表必须指定分区?

这里涉及到两种情况:select SQL查询和加载Hive表路径的方式。这里仅就"加载Hive表路径的方式"解析分区表字段,在处理时出现的一些问题及解决作出详细说明。

如果大家有类似的需求,笔者建议通过解析Spark SQL logical plan和下面说的这种方式解决方案结合,封装成一个通用的工具。

问题现象

sparksql加载指定Hive分区表路径,生成的DataSet没有分区字段。

如,

sparkSession.read.format("parquet").load(s"${hive_path}"),hive_path为Hive分区表在HDFS上的存储路径。

hive_path的几种指定方式会导致这种情况的发生(test_partition是一个Hive外部分区表,dt是它的分区字段,分区数据有dt为20200101和20200102):

1. hive_path为"/spark/dw/test.db/test_partition/dt=20200101"

2. hive_path为"/spark/dw/test.db/test_partition/*"

因为牵涉到的源码比较多,这里仅以示例的程序中涉及到的源码中的class、object和方法,绘制成xmind图如下,想细心研究的可以参考该图到spark源码中进行分析。

问题分析

我这里主要给出几个源码段,结合上述xmind图理解:

在没有指定参数basePath的情况下:

1. hive_path为/spark/dw/test.db/test_partition/dt=20200101

sparksql底层处理后得到的basePaths: Set(new Path(“/spark/dw/test.db/test_partition/dt=20200101”))【伪代码】

leafDirs: Seq(new Path(“/spark/dw/test.db/test_partition/dt=20200101”))【伪代码】

2. hive_path为/spark/dw/test.db/test_partition/*

sparksql底层处理后得到的basePaths: Set(new Path(“/spark/dw/test.db/test_partition/dt=20200101”),new Path(“/spark/dw/test.db/test_partition/dt=20200102”))【伪代码】

leafDirs: Seq(new Path(“/spark/dw/test.db/test_partition/dt=20200101”),new Path(“/spark/dw/test.db/test_partition/dt=20200102”))【伪代码】

这两种情况导致源码if(basePaths.contains(currentPath))为true,还没有解析分区就重置变量finished为true跳出循环,因此最终生成的结果也就没有分区字段:

解决方案(亲测有效)

1. 在Spark SQL加载Hive表数据路径时,指定参数basePath,如

sparkSession.read.option("basePath","/spark/dw/test.db/test_partition")

2. 主要重写basePaths方法和parsePartition方法中的处理逻辑,同时需要修改其他涉及的代码。由于涉及需要改写的代码比较多,可以封装成工具

关联文章:

Spark SQL

Apache Hive

必须掌握的分布式文件存储系统—HDFS

Spark SQL解析查询parquet格式Hive表获取分区字段和查询条件的更多相关文章

  1. Hive表种map字段的查询取用

    建表可以用 map<string,string> 查询时可以按照 aaa[bbb], aaa 是map字段名,bbb是其中的参数名,就可以取到这个参数的值了 当参数名bbb是string时 ...

  2. Spark访问与HBase关联的Hive表

    知识点1:创建关联Hbase的Hive表 知识点2:Spark访问Hive 知识点3:Spark访问与Hbase关联的Hive表 知识点1:创建关联Hbase的Hive表 两种方式创建,内部表和外部表 ...

  3. 3. Spark SQL解析

    3.1 新的起始点SparkSession 在老的版本中,SparkSQL提供两种SQL查询起始点,一个叫SQLContext,用于Spark自己提供的SQL查询,一个叫HiveContext,用于连 ...

  4. Spark DataFrame vector 类型存储到Hive表

    1. 软件版本 软件 版本 Spark 1.6.0 Hive 1.2.1 2. 场景描述 在使用Spark时,有时需要存储DataFrame数据到Hive表中,一般的存储方式如下: // 注册临时表 ...

  5. 【hive】hive表很大的时候查询报错问题

    线上hive使用环境出现了一个奇怪的问题,跑一段时间就报如下错误: FAILED: SemanticException MetaException(message:Exception thrown w ...

  6. 查找sqlserver数据库中,查询某值所表名和字段名

    有时候我们想通过一个值知道这个值来自数据库的哪个表以及哪个字段,通过一个存储过程实现的.只需要传入一个想要查找的值,即可查询出这个值所在的表和字段名. 前提是要将这个存储过程放在所查询的数据库. CR ...

  7. Oracle 查询库中所有表名、字段名、字段名说明,查询表的数据条数、表名、中文表名、

    查询所有表名:select t.table_name from user_tables t;查询所有字段名:select t.column_name from user_col_comments t; ...

  8. sql server 按月对数据表进行分区

    当某张数据表数据量较大时,我们就需要对该表进行分区处理,以下sql语句,会将数据表按月份,分为12个分区表存储数据,废话不多说,直接上脚本: use [SIT_L_TMS] --开启 XP_CMDSH ...

  9. 【转】Oracle 查询库中所有表名、字段名、表名说明、字段名说明

    转自 :http://gis-conquer.blog.sohu.com/170243422.html 查询所有表名:select t.table_name from user_tables t; 查 ...

随机推荐

  1. MYSQL连接时错误码2059解决办法

     一.问题原因: 如上图的报错提示可知,报错原因是caching_sha2_password不能加载. 这是因为8.0之后mysql更改了密码的加密规则,而目前已有的客户端连接软件还不支持Mysql8 ...

  2. mysql 快速清除数据表数据

    mysql> truncate tables; 例如: mysql> truncate email_managements;

  3. 【Luogu】P1306 斐波那契公约数 题解

    原题链接 嗯...很多人应该是冲着这个标题来的 (斐波那契的魅力) 1.分析题面 点开题目,浏览一遍题目,嗯?这么简单?还是蓝题? 再看看数据范围,感受出题人深深的好意... \(n,m \leq 1 ...

  4. 【Kata Daily 190916】String end with?(字母结尾)

    题目: Complete the solution so that it returns true if the first argument(string) passed in ends with ...

  5. 5分钟GET我使用Github 5 年总结的这些骚操作!

    我使用 Github 已经有 5 年多了,今天毫无保留地把自己觉得比较有用的 Gihub 小技巧送给关注 JavaGuide 的各位小伙伴. 这篇文章肝了很久,就挺用心的,大家看内容就知道了. 如果觉 ...

  6. C++ 基础 1:C++ 对 C 语言的增强

    1 namespace 命名空间 1.1 C++ 命名空间的定义 C++标准 引入了关键字 namespace(命名空间),可以更好地控制标识符的作用域. namespace name { ... } ...

  7. wpf 全局异常捕捉+简单日志记录

    `namespace MyApp { /// /// App.xaml 的交互逻辑 /// public partial class App : Application { public App() ...

  8. X-Height

    术语x-height是指给定字体中,任何给定尺寸下小写字母x的高度. 它提供了一种描述任意字体一般比例的方法. 在印刷中,x-height是一行文字的基线与小写字母(即不包括上升笔画或下降笔画)的主体 ...

  9. Databricks说的Lakehouse是什么?

    在过去的几年里,Lakehouse作为一种新的数据管理范式,已独立出现在Databricks的许多用户和应用案例中.在这篇文章中,我们将阐述这种新范式以及它相对于之前方案的优势. 数据仓库在决策支持和 ...

  10. Python_selenium_WebDriver API,ActionChains鼠标, Keys 类键盘

    WebDriver 提供的八种定位方法: find_element_by_id() find_element_by_name() find_element_by_class_name() find_e ...