分享

Hive高级编程之 hive -f 传参

zhuqitian 发表于 2017-3-6 09:46:52 [显示全部楼层] 回帖奖励 阅读模式 关闭右栏 1 19337
本帖最后由 zhuqitian 于 2017-3-6 10:01 编辑
问题:如何在使用hive -f时传参到脚本中,不用硬编码
办法1:
hive0.9以及之前的版本是不支持传参的
hive1.0版本之后支持  hive -f 传递参数
先创建个test.hql文件
[mw_shl_code=sql,true]select * from ods.tracklog where day='${hiveconf:day}' and requesturl like '%${hiveconf:url}%' limit 10;[/mw_shl_code]
调用命令:
[mw_shl_code=sql,true]hive -hiveconf day=20161101 -hiveconf url=baidu.com -f test.hql[/mw_shl_code]

办法2:封装jar包
[mw_shl_code=java,true]package com.adtime.hiveF.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Map;

/**
* 获取sql,并替换参数
* @author 圣斗士宙斯
*
*/
public class Utils
{
  public static final String BEGIN = "${";
  public static final String END = "}";

  public static String getSql(File file) throws FileNotFoundException  {
          FileReader fr = null;
        try {
                fr = new FileReader(file);
        } catch (FileNotFoundException e2) {
                e2.printStackTrace();
        }
    BufferedReader bf = new BufferedReader(fr);
    StringBuffer sqlBuffer = new StringBuffer();
    String temp = null;
    try {
                while ((temp = bf.readLine()) != null) {
                  String tmp = temp.trim();
                  if ((tmp.length() != 0) && (!tmp.startsWith("#")) && (!tmp.startsWith("--"))){
                    sqlBuffer.append(tmp + " ");
                  }
                }
        } catch (IOException e) {
                e.printStackTrace();
        }
    try {
                bf.close();
        } catch (IOException e) {
                e.printStackTrace();
        }
    return sqlBuffer.toString();
  }

  /**
   * 接受getSql()的返回值,用Parse()替换参数
   * @param sql
   * @param map
   * @return
   */
  public static String parse(String sql, Map<String, String> map)
  {
    int begin = sql.indexOf(BEGIN);
    while (begin != -1)
    {
      String suffix = sql.substring(begin + BEGIN.length());
      int end = begin + BEGIN.length() + suffix.indexOf("}");
      String key = sql.substring(begin + BEGIN.length(), end).trim();
      if ((map != null) && (map.get(key) != null)) {
        sql = sql.substring(0, begin) + (String)map.get(key) + sql.substring(end + 1, sql.length());
      }
      else
      {
        throw new RuntimeException("Invalid Expression.....");
      }
      begin = sql.indexOf("${");
    }
    return sql;
  }
}[/mw_shl_code]


==============

[mw_shl_code=java,true]package com.adtime.hiveF.parseArgs;

import java.util.HashMap;
import java.util.Map;

/**
* 循环解析多参数,put到map里,不以"-"开头就argsNumber++
* @author 圣斗士宙斯
*
*/
public class Parse {
        private Map<String,String> map = null;
        
        public Parse(String[] args){
                map = new HashMap<String, String>();
               
                if(args.length == 0){
                        return ;
                }
                int argsNumber = 0;
                while (argsNumber < args.length) {
                        String pre = args[argsNumber].trim();
                        if (pre.startsWith("-")) {
                                String key = pre.substring(1);
                                argsNumber++;
                                String value = "";
                                if (args.length > argsNumber) {
                                        value = args[argsNumber].trim();
                                        if (args[argsNumber].startsWith("\"") || args[argsNumber].startsWith("\'")) {
                                                value = value.substring(1,value.length() - 1);
                                        }
                                }
                                map.put(key, value);
                                argsNumber++;
                        }else {
                                argsNumber++;
                        }
                }
        }

        public Map<String, String> getMap() {
                return map;
        }
}[/mw_shl_code]

==================

[mw_shl_code=java,true]package main;

import java.io.File;

import com.adtime.hiveF.parseArgs.Parse;
import com.adtime.hiveF.util.Utils;

public class MainHive {
        public static void main(String[] args) {
                /*args = new String[5];
                args[0] = "C:/Users/zhuqitian/Desktop/dwd_ev_pub_user_act_app_rmd.txt";
                args[1] = "-date";
                args[2] = "20160627";
                args[3] = "-date2";
                args[4] = "20160628";*/
               
                Parse parse = new Parse(args);
                String sql = null;
                try {
                        sql = Utils.getSql(new File(args[0]));
                } catch (Exception e) {
                        e.printStackTrace();
                }
                System.out.println(Utils.parse(sql, parse.getMap()));
        }
}[/mw_shl_code]

================shell脚本封装一个命令
[mw_shl_code=shell,true]vi /usr/bin/.hivef

#!/bin/bash
  2
  3 . /etc/profile
  4
  5 sql=`/usr/java/jdk1.8.0_91/bin/java -jar /opt/soft/hivef.jar $*`
  6
  7 echo "${sql}"
  8
  9 hive -e "${sql}"
10
11 exit 0;

chmod 111 /usr/bin/.hivef[/mw_shl_code]
讨论:大家有好的方法可以一起讨论下
暂时还有个想法:可以完善下命令:判断下命令的第一个参数是什么,
比如是2mysql,就执行一个类(或调用另一个jar包)把hive数据同步到关系型数据库
当然可以接受其他参数,比如frommysql -table -columns -where等参数,如果觉得冗杂
可以写成配置文件的形式
以上是我的个人想法,不一定啥时候实现,如果哪位提前ok了,望与我取得联系!
zhuqitian13@126.com/284678311

本帖被以下淘专辑推荐:

已有(1)人评论

跳转到指定楼层
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条