正在做oracle到hive的数据导入,遇到数据分隔问题,sqoop2 默认分隔式逗号,我使用hive 也是逗号分隔,发现数据中含有逗号的字段,hive把它分成了好几个。于是去网上找自定义分隔的解决方法,但是无奈这方面的资料很少。不解决此问题,工作无法进行。胜了最后一个法宝,编译源码。
2、去下载跟你使用的一个版本的sqoop2 源码(最好),使用maven构建,(注意,打包时最好跳过test,进行编译,不然可能会报错)
3、修改代码:
定位:应为是写到hdfs上,所谓我认识应该写该hdfs-connector的代码,发现代码中有定义默认分隔符的,把它改成 制表符,编译->上传后,发现结果没有改变。接着思考,发现类:org.apache.sqoop.connector.hdfs.hdfsWriter.HdfsTextWriter下有个write方法,并且有个HdfsConstants.DEFAULT_RECORD_DELIMITER(每行的记录的默认分隔),
这个是每个记录以逗号分隔的的数据,现在要写个方法将其分开(把单引号作为一种标志把,字段的逗号跟非分隔符逗号分开)
4、下面是以逗号分隔改为以 ‘\t’分隔的代码(org.apache.sqoop.connector.hdfs.hdfsWriter.HdfsTextWriter整个类)
package org.apache.sqoop.connector.hdfs.hdfsWriter;
import com.google.common.base.Charsets;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.compress.CompressionCodec;
import org.apache.sqoop.connector.hdfs.HdfsConstants;
import java.io.BufferedWriter;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
public class HdfsTextWriter extends GenericHdfsWriter {
private BufferedWriter filewriter;
@Override
public void initialize(Path filepath, Configuration conf, CompressionCodec codec) throws IOException {
FileSystem fs = filepath.getFileSystem(conf);
DataOutputStream filestream = fs.create(filepath, false);
if (codec != null) {
filewriter = new BufferedWriter(new OutputStreamWriter(
codec.createOutputStream(filestream, codec.createCompressor()),
Charsets.UTF_8));
} else {
filewriter = new BufferedWriter(new OutputStreamWriter(
filestream, Charsets.UTF_8));
}
}
@Override
public void write(String csv) throws IOException {
filewriter.write(transfer(csv) + HdfsConstants.DEFAULT_RECORD_DELIMITER);
}
@Override
public void destroy() throws IOException {
filewriter.close();
}
private String transfer(String csv){
String words[]=csv.split(",");
StringBuffer sb=new StringBuffer();
boolean flag1=false;
boolean flag2=false;
boolean flag3=false;
String temp="";
for (int i = 0; i < words.length; i++) {
if(words[i].equalsIgnoreCase("NULL")){
words[i]="-1";
}
flag1=words[i].startsWith("'");
flag2=words[i].endsWith("'");
if(flag1&&flag2){
sb.append(words[i]);
sb.append('\t');
}else if(flag1&&!flag2){
temp=words[i]+",";
flag3=true;
}else if(!flag1&&flag2){
temp=temp+","+words[i];
flag3=false;
sb.append(temp);
sb.append('\t');
}else{
if(flag3){
temp=temp+words[i];
}else{
sb.append(words[i]);
sb.append('\t');
}
}
}
return sb.toString().replace("'", "").trim();
//return sb.toString().trim();
}
}
5、打包,及上传到sqoop2文件夹/webapps/sqoop/WEB-INF/lib(或许由于版本不一样而有差别,请选择connector所在的文件夹),在上传之前要把hdfs-connector,mv 到其他文件夹(为了保险),也可以删掉(不建议),也可以把hdfs-connector里的名字改掉(未试验),重启sqoop2。执行任务看看效果。
6、完成。