读取odps表数据

前言

这是我第一次写博客,在工作的这一段时间,几乎每天都会学到新的东西,做为一个普通人,我也深感自身记忆力的 一般,所以想通过博客的方式将自己在平时工作中遇到的技术点记录下来,积累的同时也能进行分享。

问题

由于需要从odps表中读取数据,所以我一开始使用的是spark自带DataSource的API方式进行数据读取,具体代码如下:

val df = spark
      .read
      .format("org.apache.spark.aliyun.odps.datasource")
      .option("spark.hadoop.fs.oss.impl", "com.aliyun.fs.oss.nat.NativeOssFileSystem")
      .option("odpsUrl", odpsUrl)
      .option("tunnelUrl", tunnelUrl)
      .option("table",  table)
      .option("project", project)
      .option("accessKeyId", accessKeyId)
      .option("accessKeySecret", accessKeySecret)
      .load()

可是我发现这样做有个问题,spark读取odps表时,对于有些类型的字段无法正常读取,例如:string,datetime类型都报无法传输的错误,所以我经过考虑后认为可以使用阿里云的maxCompute SDK提供的接口进行读取数据。

依赖


            com.aliyun.emr
            emr-core
            1.4.3


            com.aliyun.emr
            emr-maxcompute_2.11
            1.4.3

代码

第一种
使用SQLAPI接口进行数据读取,但这种方式一次只能读取一万条数据,存在局限性。

val account = new AliyunAccount(accessKeyId,  accessKeySecret)
val odps = new Odps(account)
odps.setEndpoint(odpsUrl)
odps.setDefaultProject(project)

val instance: Instance = SQLTask.run(odps, "select * from dw_user;")
instance.waitForSuccess()
val resultSet: ResultSet = SQLTask.getResultSet(instance)

while (resultSet.hasNext){

      val record: Record = resultSet.next()
      if(record.get("register_spm") != null){

        println(record.getString("user_id"))
      }

第二种
使用tunnel接口进行数据读取

val account = new AliyunAccount(accessKeyId,  accessKeySecret)
val odps = new Odps(account)
odps.setEndpoint(odpsUrl)
odps.setDefaultProject(project)

val tunnel = new TableTunnel(odps)
val spec = new PartitionSpec("year_id=2015")
tunnel.setEndpoint(tunnelUrl)

val session: TableTunnel#DownloadSession = tunnel.createDownloadSession(project, table,spec)
val count: Long = session.getRecordCount
println(count)
val tunnelReader: TunnelRecordReader = session.openRecordReader(0,count)
var i = 1
while (i<=count){

    val record: Record = tunnelReader.read()
    if(record.get("register_spm")!=null){

       println(record.getString("register_spm"))
     }
      i= i+1
   }
   
   tunnelReader.close()

你可能感兴趣的:(读取odps表数据)