Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preparing Cassandra SELECT Statements in Python

I'm trying to run prepared select queries against a Cassandra table.

The table is defined as such:

class EmailAddressLookup(Model, ModelOperations, JSONSerializer):
    __table_name__ = 'email_address_lookup'

    email_address = columns.Text(primary_key=True)
    user_id = columns.Integer(primary_key=True)

My INSERT works great. It looks like this:

i_email_lookup = session.prepare("""INSERT INTO email_address_lookup (user_id, email_address) VALUES (?, ?)""")

session.execute(i_email_lookup, (user_id, email_address))

However, my SELECT is not working. It looks like this:

s_email_lookup_by_email = session.prepare('SELECT user_id FROM email_address_lookup WHERE "email_address"=?')

session.execute(s_email_lookup_by_email, email_address)

Here's the traceback when email_address is a 27-char string:

Traceback (most recent call last):
  File "/home/thisguy/Documents/my_proj/api/models/case.py", line 428, in _lookup_usin_email
    matches = my_projcluster.select_email_lookup_by_email(self.email)
  File "/home/thisguy/Documents/my_proj/api/utils/decorators.py", line 14, in newfunc
    result = func(*args, **kwargs)
  File "/home/thisguy/Documents/my_proj/api/models/my_projcluster.py", line 203, in select_email_lookup_by_email
    session.execute(s_email_lookup_by_email, (email_address))
  File "/home/thisguy/.Envs/my_proj/lib/python3.4/site-packages/cassandra/cluster.py", line 1403, in execute
    future = self.execute_async(query, parameters, trace)
  File "/home/thisguy/.Envs/my_proj/lib/python3.4/site-packages/cassandra/cluster.py", line 1452, in execute_async
    future = self._create_response_future(query, parameters, trace)
  File "/home/thisguy/.Envs/my_proj/lib/python3.4/site-packages/cassandra/cluster.py", line 1464, in _create_response_future
    query = query.bind(parameters)
  File "/home/thisguy/.Envs/my_proj/lib/python3.4/site-packages/cassandra/query.py", line 390, in bind
    return BoundStatement(self).bind(values)
  File "/home/thisguy/.Envs/my_proj/lib/python3.4/site-packages/cassandra/query.py", line 486, in bind
    (len(values), len(col_meta)))
ValueError: Too many arguments provided to bind() (got 27, expected 1)

Okay, so Python tried to turn a 27-char string into 27 args? Let's wrap it in a tuple:

session.execute(s_email_lookup_by_email, (email_address, ))

This prevents the traceback, but the query returns None even when the data base certainly has a matching email address in it.

like image 824
Adam Steele Avatar asked Jun 13 '15 19:06

Adam Steele


1 Answers

This:

session.execute(s_email_lookup_by_email, (email_address))

doesn't really pass a 1-tuple to the execute method.

In python, to create a 1-tuple you need to follow the first element with a comma:

session.execute(s_email_lookup_by_email, (email_address,))

otherwise the parentheses are interpreted as grouping operators and that makes (email_address) equivalent to email_address without parentheses.

like image 188
soulcheck Avatar answered Sep 29 '22 13:09

soulcheck