如何在Scalding中使用Hive样式的目录结构输出数据?

时间:2015-02-24 03:08:36

标签: scalding

我们正在使用Scalding来执行ETL并将输出生成为带有分区的Hive表。因此,我们希望分区的目录名称类似于“state = CA”。我们使用TemplatedTsv如下:

pipe
   // some other ETL
   .map('STATE -> 'hdfs_state) { state: Int => "State=" + state }
   .groupBy('hdfs_state) { _.pass }
   .write(TemplatedTsv(baseOutputPath, "%s", 'hdfs_state,
          writeHeader = false,
          sinkMode = SinkMode.UPDATE,
          fields = ('all except 'hdfs_state)))

我们采用How to bucket outputs in Scalding的代码示例。 以下是我们遇到的两个问题:

    IntelliJ无法解析除之外的
  • :我错过了一些导入吗?我们不希望显式输入“fields =()”语句中的所有字段,因为字段是从groupBy语句中的代码派生的。如果明确输入,它们可能很容易不同步。
  • 这种方法看起来太麻烦,因为我们正在创建一个额外的列,以便Hive / Hcatalog可以处理目录名称。我们想知道应该采用什么方法来实现它?

非常感谢!

1 个答案:

答案 0 :(得分:0)

对不起前面的例子是伪代码。下面我将给出一个带输入数据示例的小代码。

请注意,这仅适用于Scalding版本0.12.0或更高版本

我们在下面输入的图片定义了一些购买数据,

user1   1384034400  6   75
user1   1384038000  6   175
user2   1383984000  48  3
user3   1383958800  48  281
user3   1384027200  9   7
user3   1384027200  9   11
user4   1383955200  37  705
user4   1383955200  37  15
user4   1383969600  36  41
user4   1383969600  36  21

制表符分隔,第3列是州号。这里我们有整数,但对于基于字符串的状态,您可以轻松适应。

此代码将读取输入并将它们放在“State = stateid”输出文件夹存储桶中。

class TemplatedTsvExample(args: Args) extends Job(args) {

  val purchasesPath = args("purchases")
  val outputPath    = args("output")

  // defines both input & output schema, you can also make separate for each of them
  val ioSchema = ('USERID, 'TIMESTAMP, 'STATE, 'PURCHASE)

  val Purchases =
     Tsv(purchasesPath, ioSchema)
     .read
     .map('STATE -> 'STATENAME) { state: Int => "State=" + state } // here you can make necessary changes
     .groupBy('STATENAME) { _.pass } // this is optional
     .write(TemplatedTsv(outputPath, "%s", 'STATENAME, false, SinkMode.REPLACE, ioSchema))
} 

我希望这会有所帮助。如果有什么不清楚,请问我。

您可以找到完整代码here.