yao
  • 前言
  • Mac环境配置
    • 1.python配置
  • 部署安装
    • 博客blog文档md模板
    • linux安装python3
    • Docker部署
      • Compose-bigdatabase-单组件启动(docker)
      • Compose-Spark组件-单独启动(docker)
      • Docker-通过dockerfile构建镜像(需测试)
      • docker-yaosong5仓库dockerImages汇总
      • Docker基础镜像中-所有home配置
    • gp部署
      • tt
      • 命令和第二次搭建-ok
      • gp搭建遇到的错误
      • gp集群搭建①-下载greenplum
      • gp集群搭建②-新建用户免密登录
      • gp集群搭建③-greenplum系统搭建
  • 实际问题解决
    • kafka异常
    • 数仓-解决hive处理异常json命令行转义字符的问题
  • 数据分析
    • 数据分析总结-pandas
    • 数据分析总结-numpy
  • 应用环境
    • Docker环境启动流程
Powered by GitBook
On this page
  • 前言
  • 1. 在hue中测试处理json
  • 2. 命令行调用hive

Was this helpful?

  1. 实际问题解决

数仓-解决hive处理异常json命令行转义字符的问题

Previouskafka异常Next数据分析

Last updated 6 years ago

Was this helpful?

[TOC]

前言

在etl清洗流程中,前一步处理将数据清洗到hive中,hive某字段中落有json字符串。我需要将json中的嵌套json解析为单独的字段。

解析为id_no、name、mobile、apply_id... extend_params_ip 、extend_params_ip_user_number、extend_params_contact(直接存储数组)...

重新解析到hive外部表,实际落入到hbase

但是之前落入hive的人未处理异常json的情况如上图,所以,我的处理手段是将json中的异常字符如\" 替换为"。故事就这样开始了

1. 在hue中测试处理json

可以知道:

转义字符的特殊情况,自身的转义,比如java有时候需要两个转义字符\\,或者四个转义字符\\\\。 1)java的两种情况

  • 正则表达式匹配

  • string的split函数

    这两种情况中字符串包含转义字符"\"时,需要先对转义字符自身转义,就是说需要两个转义字符"\"。(java解析后,再有正则和split自身特定进行解析)

    而当匹配字符正斜线\,则需要四个转义字符\\\\,因为,首先java(编译器?)自身先解析,转义成\\(两个\),再由正则或split的解析功能转义成一个\,才是最终要处理的字符。

    这是因为解析过程需要两次,才能在字符串中出现正斜线"\",出现后才能转义后面的字符。

2)hive中的split和正则表达式

​ hive用java写的,所以同Java一样,两种情况也需要两个"\"。如果是正则的话或者split的话,要匹配\ 需要4个\

如果hive和shell和正则再相遇,那么将是三次解析

shell语言也有转义字符,自身直接处理。 而hive语句在shell脚本中执行时,就需要先由shell转义后,再由hive处理。这个过程又造成二次转义。 所以,注意hive语句在shell脚本执行时,转义字符需要翻倍。hive处理的是shell转义后的语句,必须转以后正确,才能执行。如果是一个\,则需要6个 : \\\\\\,

本次用到函数regexp_replace第二参数本身就是一个正则,那么hive+正则,就是两次转义,对于反斜杠\,就是\\\\,对于"是\\"

hue先测试一条数据

hive<<!

set mapreduce.job.queuename=root.dw;
set hive.support.concurrency=false;

create external table if not exists ods.ods_r1_apply_risk_params_ex(row_key string,id_no string,name string,mobile string,apply_id string,apply_code string,apply_source string,apply_type string,apply_times string,user_id string,extend_params_ip string,extend_params_ip_user_number string,extend_params_contact string)
STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler' 
WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key,params:id_no,params:name,params:mobile,params:apply_id,params:apply_code,params:apply_source,params:apply_type,params:apply_times,params:user_id,params:extend_params_ip,params:extend_params_ip_user_number,params:extend_params_contact") 
TBLPROPERTIES("hbase.table.name" = "ods_r1_apply_risk_params_hb");


insert overwrite table ods.ods_r1_apply_risk_params_ex
select
      a.row_key,
      b.id_no,
      b.name,
      b.mobile,
      b.apply_id,
      b.apply_code,
      b.apply_source,
      b.apply_type,
      b.apply_times,
      b.user_id,
      extend_params_ip,
      extend_params_ip_user_number,
      extend_params_contact
from (select ods_r1_apply_risk_params.idapply_risk_params_id as row_key,ods_r1_apply_risk_params.apply_risk_params_apply_params from ods.ods_r1_apply_risk_params where ods_r1_apply_risk_params.dt=20180101 limit 1
) a lateral view default.json_tuple2(a.apply_risk_params_apply_params,'id_no','name','mobile','apply_id','apply_code','apply_source','apply_type','apply_times','user_id','extend_params') 
 b  as id_no,name,mobile,apply_id,apply_code,apply_source,apply_type,apply_times,user_id,extend_params lateral view default.json_tuple2( regexp_replace(regexp_replace(b.extend_params,'\\\\\"','"'),'\\\\\\\\"'),'ip','ip_user_number','contact') c as extend_params_ip,extend_params_ip_user_number,extend_params_contact
;
!

得到结果

当时没有细看,就直接写入到脚本开始调度

谁曾想

2. 命令行调用hive

所以直接将hue的脚本命令拷入脚本执行,结果无一正确结果,返回来看,发现会经历shell首先会解析一次,所以增加一个斜杠用8个代替

select
      regexp_replace(regexp_replace(b.extend_params,'\\\\\\\\\\"','"'),'\\\\\\\\\\\\\\\\\\"','"') ee,
      b.extend_params ep,
      a.row_key,
      b.id_no,
      b.name,
      b.mobile,
      b.apply_id,
      b.apply_code,
      b.apply_source,
      b.apply_type,
      b.apply_times,
      b.user_id,
      extend_params_ip,
      extend_params_ip_user_number,
      extend_params_contact
from (select ods_r1_apply_risk_params.idapply_risk_params_id as row_key,ods_r1_apply_risk_params.apply_risk_params_apply_params from ods.ods_r1_apply_risk_params where idapply_risk_params_id=20180101 limit 1
) a lateral view default.json_tuple2(a.apply_risk_params_apply_params,'id_no','name','mobile','apply_id','apply_code','apply_source','apply_type','apply_times','user_id','extend_params') 
 b  as id_no,name,mobile,apply_id,apply_code,apply_source,apply_type,apply_times,user_id,extend_params lateral view default.json_tuple2( regexp_replace(regexp_replace(b.extend_params,'\\\\\\\\\\"','"'),'\\\\\\\\\\\\\\\\\\"','"'),'ip','ip_user_number','contact') c as extend_params_ip,extend_params_ip_user_number,extend_params_contact
;

shell执行的时候,就可以看到解析了一次

转义字符就少了一半,第一次就是双反斜杠变为单反斜杠,最后打完收工

show的最原始

'\\\\\\\\"','"'),'\\\\\\\\\\\\"','"

参考

转义字符反斜杠\(在hive+shell以及java中注意事项)