Reputation: 11875
I'm trying to write a generic tool for copying Cassandra table contents from one keyspace to another one (probably in a different cluster). All the tables are not too large.
Here is what I do:
Session source = ...
Session destination = ...
TableMetadata table = ...
final ResultSet rs = source.execute("select * from " + table.getName());
String insertCql = ...
PreparedStatement preparedStatement = destination.prepare(insertCql);
for (Row row : rs) {
final BoundStatement boundStatement = preparedStatement.bind();
for (int i = 0; i < rs.getColumnDefinitions().size(); i++) {
// bind column value from row to bountStatement
}
session.execute(boundStatement);
}
The problem is how to copy the column value from row
to boundStatement
. I can read it with row.getObject(i)
, but there is no corresponding setObject()
in BoundStatement
.
More precisely, this method exists in version 2.2 of the driver (it's cassandra-driver-dse
), but that version does not work with Cassandra 3, and in version 3 of the driver (cassandra-driver-core
) setObject()
method does not exist. Instead, there are bunch of set()
methods, all of them require Class
, TypeToken
or TypeCodec
.
Where can I get those? ColumnDefinition
only gives me DataType
. It seems a doubtful idea to use row.getObject(i).getClass()
to get Class
.
Maybe there is a better approach to this task (schema-agnostic copying)?
I can look at DataType
if the column and make a case per type to use setString()
and so on, but this seems a bit overcomplicated and fragile.
Upvotes: 1
Views: 184
Reputation: 6667
You need to use bind variables in your insert statement and then bind the prepared statement with the column values from the result. Something along the lines of:
String insertCql = "INSERT INTO ks.tb (...) values (?,?,...)";
for (Row row : rs) {
List bindVariables = new ArrayList();
for (int i = 0; i < rs.getColumnDefinitions().size(); i++) {
bindVariables.add(rs.getObject(i));
}
final BoundStatement boundStatement = preparedStatement.bind(bindVariables.toArray(new Object[0]));
session.execute(boundStatement);
}
Upvotes: 4