阿里云大数据实战记录10:Hive 兼容模式的坑


文章目录

    • 1、前言
    • 2、什么是 Hive 兼容模式?
    • 3、为什么要开启 Hive 模式?
    • 4、有什么副作用?
    • 5、如何开启 Hive 兼容模式?
    • 6、该场景下,能不能不开启 Hive 兼容模式?
    • 7、为什么不是`DATE_FORMAT(datetime, string)`?
    • 8、小结

1、前言

今天在开发一个表单的时候,MaxCompute 抛给我一个错误:

SQL Runtime Unretryable Error: ODPS-0121125:[xx,xx] Unsupported operation - function signature DATE_FORMAT(string, string) is not supported in current mode, please set odps.sql.hive.compatible=true to use it

什么意思呢?就是告诉我 MaxCompute 不支持这个语法DATE_FORMAT(string, string),但是如果我还是想用的话可以加上一个配置:set odps.sql.hive.compatible=true,这样就可以使用以上语法。

这个报错原本的 SQL 可以抽象为:

SELECT DATE_FORMAT(FROM_UNIXTIME(1672538400),'yyyyMMdd')

也就是FROM_UNIXTIME(1672538400)返回结果被当作 STRING 数据类型处理了。而DATE_FORMAT(string, string)需要加上set odps.sql.hive.compatible=true才能正常工作。

2、什么是 Hive 兼容模式?

那么这个配置(set odps.sql.hive.compatible=true)是什么意思呢?
这个配置就是开启 Hive 兼容模式,使得在 MaxCompute SQL 中可以使用 Hive SQL 的函数语法。

3、为什么要开启 Hive 模式?

因为有一些函数的用法 MaxCompute 不支持,或者有差异,要开启 Hive 模式才能使用。
比如说上面报错:DATE_FORMAT()函数如果传入的参数是 STRING 类型,则需要开启 Hive 兼容模式才可以使用。否则就报错。

如上,MaxCompute 中,使用DATE_FORMAT()函数时,传入的参数不支持 STRING 类型,DATE_FORMAT(string,string)在 Hive SQL 才被支持,所以需要通过开启 Hive 兼容模式来使用它。

4、有什么副作用?

当然!肯定会有副作用,因为 Hive 模式和非 Hive 模式的一些函数的返回值是不同的。
比如说FROM_UNIXTIME()函数,它在 Hive 兼容模式下的返回值为 STRING 类型,而在 ODPS 1.0 和 ODPS 2.0 数据类型版本的返回值为 DATETIME 类型。

这会有什么影响呢?如果你使用过 MaxCompute 进行数据开发,一定不会陌生:MaxCompute 在数据类型一致性这方面要求会比较苛刻,绝大多数场景下数据类型不一致会无法判断

这时,要么抛出错误,要么直接返回空值,前者还容易处理,进行显性调整数据类型即可,后者就有点摸不着头脑,需要逐步排查。

所以,返回数据类型改变了,最大的影响就是取不到数据,也正因为这个原因,开发的表单一定要进行数据校验,避免翻车。

说个题外话,数据类型一致性这点在 MySQL 上几乎是看不见的,因为 MySQL 会帮我们进行隐式转换,不需要我们另外处理,所以在 MySQL 上,基本不需要太过担心数据类型的问题,正因为这点它特别适合小白入门~~

更多的“副作用”可参考下图:

参考链接:https://help.aliyun.com/zh/maxcompute/user-guide/hive-compatible-data-type-edition

image.png

5、如何开启 Hive 兼容模式?

了解了 Hive 的正面作用和副作用之后,还是决定使用,就可以打开 Hive 开关尽情“享用”啦!

设置开关语法:

set odps.sql.hive.compatible=true; -- 打开Hive兼容模式。

使用方法,放在 SQL前面,和 SQL 一起执行,每一个设置命令作为一个独立的语句,用;结尾:

set odps.sql.hive.compatible=true;   --打开Hive兼容模式
SELECT xxx FROM xxx;

为了保证无差异,把 ODPS 2.0 的设置一同加上。

set odps.sql.type.system.odps2=true; --打开MaxCompute 2.0数据类型。
set odps.sql.decimal.odps2=true;     --打开Decimal 2.0数据类型。
set odps.sql.hive.compatible=true;   --打开Hive兼容模式。
SELECT xxx FROM xxx;

所以,开启 Hive 兼容模式最终得到的解决方案如下:

set odps.sql.type.system.odps2=true; --打开MaxCompute 2.0数据类型。
set odps.sql.decimal.odps2=true;     --打开Decimal 2.0数据类型。
set odps.sql.hive.compatible=true;   --打开Hive兼容模式。
SELECT FROM_UNIXTIME(1672538400),DATE_FORMAT(FROM_UNIXTIME(1672538400),'yyyyMMdd');

结果如下:
image.png

6、该场景下,能不能不开启 Hive 兼容模式?

肯定的!查看 MaxCompute 的官方文档可以看到以下片段:

DATE_FORMAT 函数链接:https://help.aliyun.com/zh/maxcompute/user-guide/date-format

image.png

MaxCompute 的DATE_FORMAT()函数总共支持4个类型的参数:DATE、DATETIME、TIMESTAMP 和 STRING。其中三个:DATE、DATETIME 和 STRING类型只能在 Hive 兼容模式下使用,还有一个:TIMESTAMP 可以在非 Hive 兼容模式下使用。

那么使用CAST(FROM_UNIXTIME(1672538400)AS TIMESTAMP)将数据类型转化为 TIMESTAMP 便可!

set odps.sql.type.system.odps2=true; --打开MaxCompute 2.0数据类型。
set odps.sql.decimal.odps2=true; 		 --打开Decimal 2.0数据类型。
set odps.sql.hive.compatible=false;  --关闭Hive兼容模式。
select FROM_UNIXTIME(1672538400),DATE_FORMAT(CAST(FROM_UNIXTIME(1672538400) AS TIMESTAMP),'yyyyMMdd');

返回结果如下:
image.png

7、为什么不是DATE_FORMAT(datetime, string)

在上面的描述过程中,不知道你是否留意到,其实还有一个问题没有解决?

FROM_UNIXTIME()函数,它在 Hive 兼容模式下的返回值为 STRING 类型,而在 ODPS 1.0 和 ODPS 2.0 数据类型版本的返回值为 DATETIME 类型。但是我在没有开启 Hive 兼容模式下,返回的报错却是 MaxCompute 不支持这个语法DATE_FORMAT(string, string),而不是DATE_FORMAT(datetime, string)

那么实际上非 Hive 兼容模式是返回 STRING 还是 DATETIME 呢?

为了回答这个疑问,我做了一个验证:测试验证 FROM_UNIXTIME()在不同的模式下返回的数据类型。

说明:

  • 时间戳1672538400转换为时间格式是2023-01-01 10:00:00
  • DATE()是 ODPS 2.0 才有的语法,需要打开 ODPS 2.0 开关,有的项目直接设置打开 ODPS2,但为了保险起见,这里再设置一下,你可以查看项目的相关配置是否有开启,如果开启则不需要再设置。
  • 查文档可知:FROM_UNIXTIME()在 Hive 兼容模式下返回 STRING,在非 Hive 兼容模式下返回 DATETIME;

【测试1】开启 Hive 兼容模式,FROM_UNIXTIME(1672538400)是否返回 STRING 类型?

set odps.sql.type.system.odps2=true; --打开MaxCompute 2.0数据类型。
set odps.sql.decimal.odps2=true;     --打开Decimal 2.0数据类型。
set odps.sql.hive.compatible=true;   --打开Hive兼容模式。
SELECT FROM_UNIXTIME(1672538400),FROM_UNIXTIME(1672538400)='2023-01-01 10:00:00';

返回结果如下,符合预期。

image.png

【测试2】关闭 Hive 兼容模式,FROM_UNIXTIME(1672538400)是否返回 DATETIME 类型?

set odps.sql.type.system.odps2=true; --打开MaxCompute 2.0数据类型。
set odps.sql.decimal.odps2=true;     --打开Decimal 2.0数据类型。
set odps.sql.hive.compatible=false;  --关闭Hive兼容模式。
SELECT FROM_UNIXTIME(1672538400),FROM_UNIXTIME(1672538400)='2023-01-01 10:00:00';

结果如下:

image.png

什么情况?也相等?通过FROM_UNIXTIME(1672538400)='2023-01-01 10:00:00'判断进行了隐式转换?既然不管等号右边是 STRING 还是 DATATIME,都返回 true。改个方式,使用DATE()辅助判断。

说明:DATE()函数传入的值是时间格式'yyyy-MM-dd'的字符串或者 DATETIME 类型才会返回日期值,如果是时间格式'yyyy-MM-dd hh:mi:ss'的字符串,返回空值。

【测试3】改用DATE()函数辅助判断:开启 Hive 兼容模式,DATE(FROM_UNIXTIME(1672538400))是否返回空值?

set odps.sql.type.system.odps2=true; --打开MaxCompute 2.0数据类型。
set odps.sql.decimal.odps2=true;     --打开Decimal 2.0数据类型。
set odps.sql.hive.compatible=true;   --关闭Hive兼容模式。
SELECT FROM_UNIXTIME(1672538400),DATE(FROM_UNIXTIME(1672538400));

结果如下,符合预期。

image.png

【测试4】改用DATE()函数辅助判断:关闭 Hive 兼容模式,DATE(FROM_UNIXTIME(1672538400))是否返回日期?

set odps.sql.type.system.odps2=true; --打开MaxCompute 2.0数据类型。
set odps.sql.decimal.odps2=true;     --打开Decimal 2.0数据类型。
set odps.sql.hive.compatible=false;   --关闭Hive兼容模式。
SELECT FROM_UNIXTIME(1672538400),DATE(FROM_UNIXTIME(1672538400));

结果如下,符合预期。

image.png

【补充测试】DATE('2023-01-01 10:00:00')DATE(CAST('2023-01-01 10:00:00' as datetime))返回的结果是否是空值和时间字段?

set odps.sql.type.system.odps2=true; --打开MaxCompute 2.0数据类型。
SELECT DATE('2023-01-01 10:00:00'),DATE(CAST('2023-01-01 10:00:00' AS DATETIME));

返回结果如下,符合预期。

image.png

以上通过间接的方式验证了在 MaxCompute 中,FROM_UNIXTIME()在 Hive 兼容模式下返回 STRING,在非 Hive 兼容模式下返回 DATETIME。

非 Hive 兼容模式下,FROM_UNIXTIME(1672538400)确实是返回的是 DATETIME 类型,那么就是 DATETIME 类型传入DATE_FORMAT()时,会被转换为 STRING 类型进行处理。

8、小结

解决 MaxCompute 不支持这个语法DATE_FORMAT(string, string)的方法本文提供了两种:

  • 方法1:开启 Hive 兼容模式
set odps.sql.type.system.odps2=true; --打开MaxCompute 2.0数据类型。
set odps.sql.decimal.odps2=true;     --打开Decimal 2.0数据类型。
set odps.sql.hive.compatible=true;   --打开Hive兼容模式。
SELECT FROM_UNIXTIME(1672538400),DATE_FORMAT(FROM_UNIXTIME(1672538400),'yyyyMMdd');
  • 方法2:显性修改传入FROM_UNIXTIME(1672538400)返回的数据类型
set odps.sql.type.system.odps2=true; --打开MaxCompute 2.0数据类型。
set odps.sql.decimal.odps2=true; 		 --打开Decimal 2.0数据类型。
set odps.sql.hive.compatible=false;  --关闭Hive兼容模式。
select FROM_UNIXTIME(1672538400),DATE_FORMAT(CAST(FROM_UNIXTIME(1672538400) AS TIMESTAMP),'yyyyMMdd');

另外,传递给DATE_FORMAT()的参数如果是 DATETIME 类型,会被隐性转换为 STRING 处理。





往期回顾:

阿里云大数据实战记录9:MaxCompute RAM 用户与授权
阿里云大数据实战记录8:拆开 json 的每一个元素,一行一个
阿里云大数据实战记录7:如何处理生产环境表单的重复数据

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/139505.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

C语言的文件操作(炒详解)

⭐回顾回顾文件操作的相关细节⭐ 欢迎大家指正错误 📝在之前的学习中,不管增加数据,减少数据,当程序退出时,所有的数据都会销毁,等下次运行程序时,又要重新输入相关数据,如果一直像这…

JS 原型和原型链

原型和原型链 1. 了解原型和原型链1.1 原型1.2 原型链 2. 原型2.1 prototype2.2 __proto__ 隐式原型 3. 原型链 1. 了解原型和原型链 1.1 原型 原型: prototype 又称显示原型 1、原型是一个普通对象 2、只有构造函数才具备该属性 3、公有属性可操作 1.2 原型链 原…

Quartz 建表语句SQL文件

SQL文件在jar里面,github下载 https://github.com/quartz-scheduler/quartz/releases/tag/v2.3.2 解压,sql文件路径:quartz-core\src\main\resources\org\quartz\impl\jdbcjobstore tables_mysql_innodb.sql # # In your Quartz propertie…

Python学习 day01(注意事项)

注释 变量 数据类型的转换 运算符 / 的结果为浮点数。若// 的两边有一个为浮点数,则结果为浮点数,否则为整数。 字符串

uqrcode+uni-app 微信小程序生成二维码

使用微信小程序需要弹出动态二维码的需求,从插件市场选了一个下载次数较多的组件引入到项目中uqrcode,使用步骤如下: 1、从插件市场下载 插件地址:https://ext.dcloud.net.cn/plugin?id1287,若你是跟我一样是用uni-…

AI视频剪辑:批量智剪技巧大揭秘

对于许多内容创作者来说,视频剪辑是一项必不可少的技能。然而,传统的视频剪辑方法需要耗费大量的时间和精力。如今,有一种全新的剪辑方式正在改变这一现状,那就是批量AI智剪。这种智能化的剪辑方式能够让你在短时间内轻松剪辑大量…

【无标题】mysql 普通用户连接报错: MySql server has gone away

1、mysql 普通用户连接报错: MySql server has gone away 2、进入mysql错误日志位置查看输出日志显示错误为: [Warning] [MY-013130] [Server] Aborted connection 47 to db: unconnected user: tjcx host: 10.195.11.4 (init_connect command failed; …

嵌入式网络接口之MAC芯片与PHY芯片

目录 0. 参考文档 1.嵌入式网络接口简介 2.嵌入式网络硬件架构方案 2.1 SOC内未集成MAC芯片 2.2 SOC内集成MAC芯片 2.3 主流方案总结 2.3 参照实际网卡的说明 3.MII/RMII及MDIO接口 3.1 MII 3.2 RMII 3.3 MDIO 0. 参考文档 网卡构造:MAC与PHY的关系&…

【李沐深度学习笔记】矩阵计算(5)

课程地址和说明 线性代数实现p4 本系列文章是我学习李沐老师深度学习系列课程的学习笔记,可能会对李沐老师上课没讲到的进行补充。 本节是第五篇,由于CSDN限制,只能被迫拆分 矩阵计算 多元函数的等高线 此处参考视频:熟肉)多元…

上PICO,沉浸式观看亚运直播,参与跨国界游戏竞技

备受瞩目的杭州第19届亚运会,将于9月23日正式开幕。据悉,这也是有史以来项目最多的一届亚运会,除部分传统奥运项目外,还包含武术、藤球、板球、克柔术、柔术等亚洲特色项目,以及霹雳舞、电子竞技等深受年轻人喜爱的新兴…

LeetCode算法动态规划—斐波那契数列

目录 剑指 Offer 10- I. 斐波那契数列 - 力扣(LeetCode) 题解: 代码: 运行结果: 写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项(即 F(N)&#…

Labelme分割标注软件

Labelme分割标注软件 1、环境配置与安装1.1 创建conda虚拟环境(建议)1.2 安装Labelme 2、简单使用2.1 创建label标签文件2.2 启动labelme2.3 打开文件/文件夹2.4 设置保存结果路径2.5 标注目标2.6 保存json文件格式 3 格式转换3.1 转换语义分割标签3.2 转换实例分割标签 相关重…

中通快递一键查询,轻松掌握物流信息

在如今的快速发展的电商时代,快递已成为人们生活中不可或缺的一部分。随着快递业务的繁荣,快递公司也纷纷推出了各种查询方式,方便顾客随时掌握自己包裹的物流信息。在这其中,中通快递无疑是许多人选择的首选。下面,我…

【00】FISCO BCOS区块链简介

官方文档:https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/introduction.html FISCO BCOS是由国内企业主导研发、对外开源、安全可控的企业级金融联盟链底层平台,由金链盟开源工作组协作打造,并于2017年正式对外开源。 F…

❤Uniapp报npx update-browserslist-db@latest

❤ Uniapp报npx update-browserslist-dblatest 按照提示先更新一下 npx update-browserslist-dblatest然后打开一下端口

MATLAB实现相关性分析

目录 一.基本理论 二.两类相关系数的对比 三.相关系数的假设检验 四.MATLAB的相关操作 五.其他有关的一些列技巧 六.案例展示 七.实战操作 一.基本理论 所谓相关系数,本质上是来衡量两组数据的关系大小——对应呈现函数关心的两种变量,那么我们可以…

MySQL数据库 -- 入门篇

1. MySQL概述 1.1 数据库相关概念 三个概念:数据库、数据库管理系统、SQL。 目前主流的关系型数据库管理系统的市场占有率排名如下: Oracle:大型的收费数据库,Oracle公司产品,价格昂贵。MySQL:开源免费…

DA5 网站用户没有补全的信息

目录 1.题目描述 2.输入描述 3.输出描述 4.题目分析 5.通过代码 1.题目描述 现有一个Nowcoder.csv文件,它记录了牛客网的部分用户数据,包含如下字段(字段与字段之间以逗号间隔): Nowcoder_ID:用户ID …

【MySQL】 MySQL的增删改查(进阶)--贰

文章目录 🛫新增🛬查询🌴聚合查询🚩聚合函数🎈GROUP BY子句📌HAVING 🎋联合查询⚾内连接⚽外连接🧭自连接🏀子查询🎡合并查询 🎨MySQL的增删改查(…

【面试必刷TOP101】 删除有序链表中重复的元素-I 删除有序链表中重复的元素-II

目录 题目:删除有序链表中重复的元素-I_牛客题霸_牛客网 (nowcoder.com) 题目的接口: 解题思路: 代码: 过啦!!! 题目:删除有序链表中重复的元素-II_牛客题霸_牛客网 (nowcoder…