Spark Cassandra 连接器的行为不同于 CQL shell - 插入问题
Spark Cassandra Connector behaves different from CQL shell - Insert issue
我有以下 Cassandra DM:
CREATE TABLE table (
id uuid,
timestamp timestamp STATIC,
value1 text STATIC,
value2 int,
value3 text,
data map <text,text>,
PRIMARY KEY ( id, value2 )
);
到目前为止一切顺利。现在我必须要先插入格式类型:
INSERT INTO table (id, timestamp, value1)
VALUES (<uuid>,<timestamp>,<some-string>);
和
INSERT INTO table (id, value2, value3, data)
VALUES (<some-id>,<some-int>,<some-string>, <some-simple-json-map>)
两个 CQL 语句都可以正常工作。
现在我正在开发我的 spark 流应用程序获取数据并将其格式化为样式类似于我的 CQL 语句的数据帧。我为每组语句 1 得到几组语句 2。
现在我在保存数据帧时遇到了问题,就像第一个 CQL 语句 spark 引发了 cassandra 异常:
java.lang.IllegalArgumentException:
Some primary key columns are missing in RDD or have not been selected: value2
at com.datastax.spark.connector.writer.TableWriter$.checkMissingPrimaryKeyColumns(TableWriter.scala:190)
at com.datastax.spark.connector.writer.TableWriter$.checkColumns(TableWriter.scala:257)
at com.datastax.spark.connector.writer.TableWriter$.apply(TableWriter.scala:275)
at com.datastax.spark.connector.RDDFunctions.saveToCassandra(RDDFunctions.scala:36)
...
这是我的数据框的架构:
root
|-- id: string (nullable = true)
|-- timestamp: long (nullable = true)
|-- value1: string (nullable = true)
我的存档:
data.select("id", "timeStamp", "value1")
.write.format("org.apache.spark.sql.cassandra")
.mode(SaveMode.Append)
.options(Map("keyspace" -> "some_keyspace","table" -> "table"))
.save()
当我将值 2 列添加到我的数据框时,语句工作正常。
root
|-- id: string (nullable = true)
|-- timestamp: long (nullable = true)
|-- value1: string (nullable = true)
|-- value2: integer (nullable = false)
有没有办法在不更改数据模型的情况下使其像 CQL 语句一样工作?
静态列是一种特殊的列,由同一分区的所有行共享。在第一个插入示例中,CQL 允许您为分区插入仅静态数据:
insert into ctest (id, timestamp, value1) VALUES (233177ff-439b-4a2d-a8b0-4db742b4bc1b, '2013-01-01 00:05+0000', 'one');
select * from ctest;
id | value2 | timestamp | value1 | data | value3
--------------------------------------+--------+--------------------------+--------+------+--------
233177ff-439b-4a2d-a8b0-4db742b4bc1b | null | 2013-01-01 00:05:00+0000 | one | null | null
这将创建一个合成行;它看起来像一行,但它只是一个分区键和一个静态列。如果插入一个有主键的真实行,空值将消失:
insert into ctest (id, value2) VALUES (233177ff-439b-4a2d-a8b0-4db742b4bc1b, 1);
select * from ctest;
id | value2 | timestamp | value1 | data | value3
--------------------------------------+--------+--------------------------+--------+------+--------
233177ff-439b-4a2d-a8b0-4db742b4bc1b | 1 | 2013-01-01 00:05:00+0000 | one | null | null
(1 rows)
执行了两次插入后,您只有一行。
Spark-Cassandra 连接器更严格,不允许您为分区插入仅静态数据。连接器代码检查是否定义了主键中的所有列。它在主键 ( id, value2 ) 中找到两列,只设置了一个并引发错误。以下是 com.datastax.spark.connector.writer.TableWriter:
中的签到
private def checkMissingPrimaryKeyColumns(table: TableDef, columnNames: Seq[String]) {
val primaryKeyColumnNames = table.primaryKey.map(_.columnName)
val missingPrimaryKeyColumns = primaryKeyColumnNames.toSet -- columnNames
if (missingPrimaryKeyColumns.nonEmpty)
throw new IllegalArgumentException(
s"Some primary key columns are missing in RDD or have not been selected: ${missingPrimaryKeyColumns.mkString(", ")}")
}
有关这方面的更多背景知识,Learning Apache Cassandra 作者 Mat Brown 讨论了 static-only 第 53-54 页的插入内容。
我有以下 Cassandra DM:
CREATE TABLE table (
id uuid,
timestamp timestamp STATIC,
value1 text STATIC,
value2 int,
value3 text,
data map <text,text>,
PRIMARY KEY ( id, value2 )
);
到目前为止一切顺利。现在我必须要先插入格式类型:
INSERT INTO table (id, timestamp, value1)
VALUES (<uuid>,<timestamp>,<some-string>);
和
INSERT INTO table (id, value2, value3, data)
VALUES (<some-id>,<some-int>,<some-string>, <some-simple-json-map>)
两个 CQL 语句都可以正常工作。 现在我正在开发我的 spark 流应用程序获取数据并将其格式化为样式类似于我的 CQL 语句的数据帧。我为每组语句 1 得到几组语句 2。
现在我在保存数据帧时遇到了问题,就像第一个 CQL 语句 spark 引发了 cassandra 异常:
java.lang.IllegalArgumentException:
Some primary key columns are missing in RDD or have not been selected: value2
at com.datastax.spark.connector.writer.TableWriter$.checkMissingPrimaryKeyColumns(TableWriter.scala:190)
at com.datastax.spark.connector.writer.TableWriter$.checkColumns(TableWriter.scala:257)
at com.datastax.spark.connector.writer.TableWriter$.apply(TableWriter.scala:275)
at com.datastax.spark.connector.RDDFunctions.saveToCassandra(RDDFunctions.scala:36)
...
这是我的数据框的架构:
root
|-- id: string (nullable = true)
|-- timestamp: long (nullable = true)
|-- value1: string (nullable = true)
我的存档:
data.select("id", "timeStamp", "value1")
.write.format("org.apache.spark.sql.cassandra")
.mode(SaveMode.Append)
.options(Map("keyspace" -> "some_keyspace","table" -> "table"))
.save()
当我将值 2 列添加到我的数据框时,语句工作正常。
root
|-- id: string (nullable = true)
|-- timestamp: long (nullable = true)
|-- value1: string (nullable = true)
|-- value2: integer (nullable = false)
有没有办法在不更改数据模型的情况下使其像 CQL 语句一样工作?
静态列是一种特殊的列,由同一分区的所有行共享。在第一个插入示例中,CQL 允许您为分区插入仅静态数据:
insert into ctest (id, timestamp, value1) VALUES (233177ff-439b-4a2d-a8b0-4db742b4bc1b, '2013-01-01 00:05+0000', 'one');
select * from ctest;
id | value2 | timestamp | value1 | data | value3
--------------------------------------+--------+--------------------------+--------+------+--------
233177ff-439b-4a2d-a8b0-4db742b4bc1b | null | 2013-01-01 00:05:00+0000 | one | null | null
这将创建一个合成行;它看起来像一行,但它只是一个分区键和一个静态列。如果插入一个有主键的真实行,空值将消失:
insert into ctest (id, value2) VALUES (233177ff-439b-4a2d-a8b0-4db742b4bc1b, 1);
select * from ctest;
id | value2 | timestamp | value1 | data | value3
--------------------------------------+--------+--------------------------+--------+------+--------
233177ff-439b-4a2d-a8b0-4db742b4bc1b | 1 | 2013-01-01 00:05:00+0000 | one | null | null
(1 rows)
执行了两次插入后,您只有一行。
Spark-Cassandra 连接器更严格,不允许您为分区插入仅静态数据。连接器代码检查是否定义了主键中的所有列。它在主键 ( id, value2 ) 中找到两列,只设置了一个并引发错误。以下是 com.datastax.spark.connector.writer.TableWriter:
中的签到 private def checkMissingPrimaryKeyColumns(table: TableDef, columnNames: Seq[String]) {
val primaryKeyColumnNames = table.primaryKey.map(_.columnName)
val missingPrimaryKeyColumns = primaryKeyColumnNames.toSet -- columnNames
if (missingPrimaryKeyColumns.nonEmpty)
throw new IllegalArgumentException(
s"Some primary key columns are missing in RDD or have not been selected: ${missingPrimaryKeyColumns.mkString(", ")}")
}
有关这方面的更多背景知识,Learning Apache Cassandra 作者 Mat Brown 讨论了 static-only 第 53-54 页的插入内容。