解决java - Converting cassandra blob type to string

 

I have an old column family which has a column named "value" which was defined as a blob data type. This column usually holds two numbers separated with an underscore, like "421_2".

When im using the python datastax driver and execute the query, the results return with that field parsed as a string:

In [21]: session.execute(q)
Out[21]: 
[Row(column1=4776015, value='145_0'),
 Row(column1=4891778, value='114_0'),
 Row(column1=4891780, value='195_0'),
 Row(column1=4893662, value='105_0'),
 Row(column1=4893664, value='115_0'),
 Row(column1=4898493, value='168_0'),
 Row(column1=4945162, value='148_0'),
 Row(column1=4945163, value='131_0'),
 Row(column1=4945168, value='125_0'),
 Row(column1=4945169, value='211_0'),
 Row(column1=4998426, value='463_0')]

When I use the java driver I get a com.datastax.driver.core.Row object back. When I try to read the value field by, for example, row.getString("value") I get the expected InvalidTypeException: Column value is of type blob. Seems like the only way to read the field is via row.getBytes("value") and then I get back an java.nio.HeapByteBuffer object.

Problem is, I cant seem to convert this object to string in an easy fashion. Googling yielded two answers from 2012 that suggest the following:

String string_value = new String(result.getBytes("value"), "UTF-8");

But such a String constructor doesn't seems to exist anymore. So, my questions are:

  1. How do I convert HeapByteBuffer into string?
  2. How come the python driver converted the blob easily and the java one did not?

Side Note: I could debug the python driver, but currently that seems too much work for something that should be trivial. (and the fact that no one asked about it suggests Im missing something simple here..)

java cassandra blob cql datastax 
 | 
  this question
 asked Aug 4 '15 at 17:37 idoda 1,329 3 19 36



 | 

Answers
4

Solution

Another easier way is to change the CQL statement.

select column1, blobastext(value) from YourTable where key = xxx

The second column would be type of String.


 | 
  this answer
 answered Aug 5 '15 at 1:26 popcorny 677 7 9      I like this one, but Im not sure how easy it is to incorporate it in the Java driver.. going to check. –  idoda Aug 5 '15 at 8:33      I didnt find a way to apply a function to a selected column in the Java QueryBuilder object supplied by Datastax. Otherwise that would have been a very elegant solution. –  idoda Aug 5 '15 at 12:45      Why don't you use session.execute("select column, ....") directly? If you need to use QueryBuilder, try Selection.Selection::fcall. I am very sure that blobastext works in java driver, because i used it in my production project. –  popcorny Aug 5 '15 at 14:20      Do you know how to programatically create a blob from string? the fcall is only available in selection for some reason. What If I need now to update, for example, a blob column? –  idodaAug 10 '15 at 12:25      @idoda it should be textAsBlob(?) –  Andrew James Ramirez Jun 16 '16 at 8:24



 | 

You can also get direct access to the Java driver's serializers. This way you don't have to deal with low-level details, and it also works for other types.

Driver 2.0.x:

String s = (String)DataType.text().deserialize(byteBuffer);

Driver 2.1.x:

ProtocolVersion protocolVersion = cluster.getConfiguration().getProtocolOptions().getProtocolVersion();
String s = (String)DataType.text().deserialize(byteBuffer, protocolVersion);

Driver 2.2.x:

ProtocolVersion protocolVersion = cluster.getConfiguration().getProtocolOptions().getProtocolVersion();
String s = TypeCodec.VarcharCodec.instance.deserialize(byteBuffer, protocolVersion);


 | 
  this answer
 answered Aug 4 '15 at 20:00 Olivier Michallat 1,534 3 8 1   Great answer! Listing out how each driver version differs will help others out a lot, too. –  Aaron Aug 4 '15 at 20:02      @BryceAtNetwork23 I agree, elaborated answer, thanks Olivier! –  idoda Aug 5 '15 at 8:45      Any idea if its possible to do the TypeCodec dynamically based on what the DataType.getType() is ? I am trying to convert a library thats using this approach quite heavily to 2.2. –  Artii Nov 20 '15 at 18:04      Any idea for 3.0.x driver? Where did you find it? –  Andrew James Ramirez Jun 16 '16 at 8:59



 | 

1.) Converting from byte buffer in Java is discussed in this answer.

2.) Assuming you're using Python 2, it's coming back as a string in Python because str is the binary type.


 | 
  this answer
 answered Aug 4 '15 at 19:00 Adam Holmberg 4,884 2 22 42      And in java? can you elaborate more? thanks :) –  idoda Aug 5 '15 at 8:33



 | 

For version 3.1.4 of the datastax java driver the following will convert a blob to a string:

ProtocolVersion proto = cluster.getConfiguration().getProtocolOptions().getProtocolVersion();

String deserialize = TypeCodec.varchar().deserialize(row.getBytes(i), proto);
Published 19 original articles · praised 4 · 170,000 views +

Guess you like

Origin blog.csdn.net/u011250186/article/details/105340367