Spark - 使用额外列将数据从表移动到新表

时间:2017-07-07 05:56:19

标签: scala apache-spark cassandra tuples rdd

所以我们有一个Cassandra项目,它要求我们将3个独立的表中的大量表迁移到一个表中。

e.g。 table_d_abctable_m_abctable_w_abctable_t_abc

基本上,数据需要移动到这个新表,并带有一个额外的列,其值在表的名称中。 有100个这样的表 - 所以你可以想象“手工制作”迁移脚本的巨大工作。我自然认为SPARK应该能够胜任这项工作。

e.g:

var tables = List("table_*_abc", "table_*_def") // etc
var periods = List('d','w','m')

for (table <- tables) {
  for (period <- periods) {
    var rTable = table.replace('*', period)
    var nTable = table.replace('*', 't')
    try {
      var t = sc.cassandraTable("data", rTable)
      var fr = t.first
      var columns = fr.toMap.keys.toArray :+ "period"
      var data = t.map(_.iterator.toArray :+ period)

      // This line does not work as data is a RDD of Array[Any] and not RDD of tuple[...]
      // How to ???
      data.saveToCassandra("data", nTable, SomeColumns(columns.map(ColumnName(_)):_*))
    } //catch {}
  }
}

var periods = List('d','w','m')

for (period <- periods) {
  sc.cassandraTable("data","table_" + period + "_abc")
    .map(v => (v.getString("a"), v.getInt("b"), v.getInt("c"), period))
    .saveToCassandra("data", "table_t_abc", SomeColumns("a","b","c","period"))

  // ... 100s of other scripts like this
}

我正在尝试做什么?

有没有办法以编程方式从具有未知列数和数据类型的源中保存额外的列?

1 个答案:

答案 0 :(得分:1)

这里的问题是RDD对象必须是一个定义了“RowWriter”的类型。这会将对象中的数据映射到C *可插入缓冲区。

RDD World

使用“CassandraRow”对象这是可能的。这些对象允许通用内容,并且可以在文件上构建。它们也是默认输出,因此从旧版本中创建一个新输出应该相对便宜。

https://github.com/datastax/spark-cassandra-connector/blob/master/spark-cassandra-connector/src/main/scala/com/datastax/spark/connector/CassandraRow.scala

您将使用附加列为每个表创建一个RowMetadata(基本上是模式信息),然后使用输入行的值+新周期变量填充该行。

Dataframe World

如果您想切换到Dataframes,这将更容易,因为您可以在保存之前使用DataFrame添加列。

cassandraDF.withColumn("period",lit("Value based on first row"))