在前一个STEP中,我们完成了ODPS的数据下载。
本blog记录如何完成上传。
@Override
public boolean UpdateOdps() {
//初始化需要录入的数据
List<Map> List_model = read();
TableTunnel tunnel = new TableTunnel(odps);
Date date=new Date();//取时间
Date yesterday = new Date(date.getTime() + -1 * 24 * 60 * 60 * 1000L);
java.text.SimpleDateFormat format = new java.text.SimpleDateFormat("yyyyMMdd", java.util.Locale.CHINA);
String result = format.format(yesterday);
String partition = "ds='"+result.substring(0,8)+"'"; //patition需要的是一个表达式
logger.info("today's partitio_updateodps: "+partition);
// 初始化 MaxCompute 和 tunnel 的代码
RecordWriter writer = null;
try {
/*PartitionSpec类表示一个特定分区的定义*/
PartitionSpec partitionSpec = new PartitionSpec(partition);
Table table = odps.tables().get("netdev_as_save_api");//获取当前表
boolean a = table.hasPartition(partitionSpec);//判断上述定义分区在表中是否存在
if (a) {
System.out.println("分区已经存在,可以直接上传数据");
} else {
System.out.println("分区不存在,先创建分区再上传数据");
table.createPartition(partitionSpec);
}
TableTunnel.UploadSession uploadSession = tunnel.createUploadSession(odps.getDefaultProject(),
"你的表名", partitionSpec);
// 准备数据后打开Writer开始写入数据,准备数据后写入一个Block
// 单个Block内写入数据过少会产生大量小文件 严重影响计算性能, 强烈建议每次写入64MB以上数据(100GB以内数据均可写入同一Block)
// 可通过数据的平均大小与记录数量大致计算总量即 64MB < 平均记录大小*记录数 < 100GB
// 生成TunnelBufferedWriter的实例
writer = uploadSession.openBufferedWriter();
Record product = uploadSession.newRecord();
for (Map map : List_model) {
product.setString("string1",map.get("string1").toString());
product.setString("string2",map.get("string2").toString());
// 调用write接口写入数据
writer.write(product);
}
if (writer != null) {
// 关闭TunnelBufferedWriter
writer.close();
}
// uploadSession提交,结束上传
uploadSession.commit();
return true;
}
catch (TunnelException e ) {
e.printStackTrace();
return false;
}catch (IOException e) {
e.printStackTrace();
return false;
}catch (OdpsException e) {
e.printStackTrace();
return false;
}
}
有一些额外的小坑:
1. a.toString().equals(null)是不成立的,必须使用a == null 的判断式(在做数据预处理时)
2.所有的Implement的具体实现上都要@Service,否则无法自动注册Bean;而Service本身则不@Service避免操作Bean名重复(如果有多个Implement对应一个Service)则需要使用@Qualifier
涉及到ODPS的坑:
1.PARTITION不是直接传20190702就行,而是要传ds='20190702'
2.向分区表写入时,默认不会创建分区表,因此要手工创建。手工创建使用SQLTask是无法创建的,需要使用createPartition
https://blog.csdn.net/jyl932099427/article/details/47612519
3.如果变量为null,好像上传会有些问题(会报nullexception的空指针错误)。现在暂时是把null值都滤掉了,后面再研究怎么上传null值
4.