简体   繁体   中英

Ruby: how to insert Hash value into Cassandra map

Am attempting to store values provided as int, time, hash into Cassandra using Datastax driver.

Hash appears as { "Q17.1_4"=>"val", "Q17.2"=>"other", ... }

Have defined table as:

  • int
  • timestamp
  • map
  • PK( int, timestamp )

I can get the PK inserted ok but am having trouble coercing the hash values into something that Cassandra can cope with.

Have created a prepared statement and using it while (trying to) looping through values:

stmt = session.prepare( "insert into forms( id, stamp, questions ) values ( ?,?,? )" )

...
json_val.each{ |key,val|
    result = session.execute( stmt, val[ 'ID' ].to_i, Time.parse( val[ 'tDate' ]).to_i, val )
}

If I insert 'val' as a hash I get this error:

/lib/cassandra/statements/prepared.rb:53:in `bind': expecting exactly 3 bind parameters, 2 given (ArgumentError)

This says (to me) that there isn't a method to convert the hash to what Cassandra wants.

If I insert the val as a string (using hash.to_s ) I get this error:

/lib/cassandra/protocol/type_converter.rb:331:in varchar_to_bytes': undefined method encode' for 1:Fixnum (NoMethodError)

... same goes for converting it to a json string, changing double quotes to single and so on.

I can insert the values using the cqlsh (command line) ( EG insert into forms (id, stamp, questions) values ( 123, 12345678, { 'one':'two','three':'four'}); )

So the question is - how do I get this Ruby hash into a format that the Cassandra driver will accept?

Using:

  • Ruby 2.1.3
  • Cassandra 2.0 (with latest Datastax driver)

EDIT:

JSON value of 'questions' hash is { "Q17.1_4":"val", "Q17.2":"other", ...}

Also - I can insert the first two columns just fine. Omitting the third value from the insert statement works so I know those two values aren't the culprit here.

Found two problems:

  1. There is a note in the docs:

Last argument will be treated as options if it is a Hash. Therefore, make sure to pass empty options when executing a statement with the last parameter required to be a map datatype.

  1. When I either put an empty hash as the last parameter or swapped my hash value for a different param the error message changed to:

type_converter.rb:331:in varchar_to_bytes': undefined method encode' for 1:Fixnum (NoMethodError)

This lead me to believe that there was an invalid value in there somewhere. To fix this I created a temp hash and checked every value to make sure it was a string before adding it to this temp hash. Then using this temp value I was able to add to the DB using the stored procedure.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM