Skip to content

Commit 4c8abd1

Browse files
committed
[PYTHON-491] Integration tests for named parameters in queries
1 parent 4d8cfdf commit 4c8abd1

3 files changed

Lines changed: 141 additions & 3 deletions

File tree

docs/getting_started.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ Named place-holders use the ``%(name)s`` form:
179179
"""
180180
INSERT INTO users (name, credits, user_id, username)
181181
VALUES (%(name)s, %(credits)s, %(user_id)s, %(name)s)
182-
"""
182+
""",
183183
{'name': "John O'Reilly", 'credits': 42, 'user_id': uuid.uuid1()}
184184
)
185185

tests/integration/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ def _get_cass_version_from_dse(dse_version):
136136
PROTOCOL_VERSION = int(os.getenv('PROTOCOL_VERSION', default_protocol_version))
137137

138138
notprotocolv1 = unittest.skipUnless(PROTOCOL_VERSION > 1, 'Protocol v1 not supported')
139-
lessthenprotocolv4 = unittest.skipUnless(PROTOCOL_VERSION < 4, 'Protocol versions 4 or greater not supported')
139+
lessthanprotocolv4 = unittest.skipUnless(PROTOCOL_VERSION < 4, 'Protocol versions 4 or greater not supported')
140140
greaterthanprotocolv3 = unittest.skipUnless(PROTOCOL_VERSION >= 4, 'Protocol versions less than 4 are not supported')
141141

142142
greaterthancass20 = unittest.skipUnless(CASSANDRA_VERSION >= '2.1', 'Cassandra version 2.1 or greater required')

tests/integration/standard/test_query.py

Lines changed: 139 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@
2626
from cassandra.cluster import Cluster
2727
from cassandra.policies import HostDistance
2828

29-
from tests.integration import use_singledc, PROTOCOL_VERSION, BasicSharedKeyspaceUnitTestCase, get_server_versions, greaterthanprotocolv3
29+
from tests.integration import use_singledc, PROTOCOL_VERSION, BasicSharedKeyspaceUnitTestCase, get_server_versions, \
30+
greaterthanprotocolv3, greaterthancass20
3031

3132
import re
3233

@@ -202,6 +203,95 @@ def test_column_names(self):
202203
result_set = self.session.execute("SELECT * FROM {0}.{1}".format(self.keyspace_name, self.function_table_name))
203204
self.assertEqual(result_set.column_names, [u'user', u'game', u'year', u'month', u'day', u'score'])
204205

206+
def create_param_table(self):
207+
self.session.execute("""CREATE TABLE IF NOT EXISTS {0}.users(
208+
user_id BIGINT PRIMARY KEY,
209+
first VARCHAR,
210+
last VARCHAR,
211+
age BIGINT
212+
)""".format(self.keyspace_name))
213+
214+
def test_positional_params(self):
215+
"""
216+
Test to validate positional parameters
217+
218+
test_positional_params tests that positional parameters can be used in a query. It first creates a simple table.
219+
It then inserts into this table using positional parameters. Finally, it performs a select query and verifies
220+
that the data has been properly written and retrieved.
221+
222+
@since 3.2.0
223+
@jira_ticket PYTHON-491
224+
@expected_result positional params should be parsed by the driver.
225+
226+
@test_category queries:basic
227+
"""
228+
229+
self.create_param_table()
230+
self.session.execute("""INSERT INTO {0}.users (user_id, first, last, age)
231+
VALUES (%s, %s, %s, %s)
232+
""".format(self.keyspace_name),
233+
(0, 'John', 'Doe', 40))
234+
235+
result = self.session.execute("SELECT * FROM {0}.users WHERE user_id=%s".format(self.keyspace_name), (0,))[0]
236+
self.assertEqual(result.user_id, 0)
237+
self.assertEqual(result.first, 'John')
238+
self.assertEqual(result.last, 'Doe')
239+
self.assertEqual(result.age, 40)
240+
241+
@greaterthancass20
242+
def test_named_params(self):
243+
"""
244+
Test to validate named parameters
245+
246+
test_named_params tests that named parameters can be used in a query. It first creates a simple table.
247+
It then inserts into this table using named parameters. Finally, it performs a select query and verifies
248+
that the data has been properly written and retrieved.
249+
250+
@since 3.2.0
251+
@jira_ticket PYTHON-439
252+
@expected_result named params should be parsed by the driver.
253+
254+
@test_category queries:named_parameters
255+
"""
256+
257+
self.create_param_table()
258+
self.session.execute("""INSERT INTO {0}.users (user_id, first, last, age)
259+
VALUES (%(a)s, %(b)s, %(c)s, %(d)s)
260+
""".format(self.keyspace_name),
261+
{'a': 0, 'b': 'John', 'c': 'Doe', 'd': 40})
262+
263+
result = self.session.execute("SELECT * FROM {0}.users WHERE user_id=%(id)s".format(self.keyspace_name), {'id': 0})[0]
264+
self.assertEqual(result.user_id, 0)
265+
self.assertEqual(result.first, 'John')
266+
self.assertEqual(result.last, 'Doe')
267+
self.assertEqual(result.age, 40)
268+
269+
@greaterthancass20
270+
def test_raise_error_on_invalid_named_params(self):
271+
"""
272+
Test to validate invalid named parameters
273+
274+
test_raise_error_on_invalid_named_params tests that named parameters with missing arguments cannot be used in a
275+
query. It first creates a simple table. It then inserts into this table using named parameters, with one missing
276+
argument. It verifies that a KeyError is raised in this case.
277+
278+
@expected_errors KeyError When there is a missing parameter.
279+
280+
@since 3.2.0
281+
@jira_ticket PYTHON-439
282+
@expected_result A KeyError should be raised due to missing arguments.
283+
284+
@test_category queries:named_parameters
285+
"""
286+
287+
self.create_param_table()
288+
289+
with self.assertRaises(KeyError):
290+
self.session.execute("""INSERT INTO {0}.users (user_id, first, last, age)
291+
VALUES (%(a)s, %(b)s, %(c)s, %(d)s)
292+
""".format(self.keyspace_name),
293+
{'a': 0, 'b': 'John', 'c': 'Doe'})
294+
205295

206296
class PreparedStatementTests(unittest.TestCase):
207297

@@ -438,6 +528,54 @@ def test_unicode(self):
438528
finally:
439529
self.session.execute("DROP TABLE test3rf.testtext")
440530

531+
@greaterthancass20
532+
def test_named_params_in_batches(self):
533+
"""
534+
Test to validate named parameters with batches
535+
536+
test_named_params_in_batches tests that named parameters can be used in a query for a batch statement. It first
537+
creates a simple table. It then inserts into this table using named parameters inside of a batch. Finally, it
538+
performs a select query and verifies that the data has been properly written and retrieved.
539+
540+
@since 3.2.0
541+
@jira_ticket PYTHON-439
542+
@expected_result named params should be parsed by the driver.
543+
544+
@test_category queries:named_parameters
545+
"""
546+
547+
self.session.execute("""CREATE TABLE IF NOT EXISTS {0}.users(
548+
user_id BIGINT PRIMARY KEY,
549+
first VARCHAR,
550+
last VARCHAR,
551+
age BIGINT
552+
)""".format(self.keyspace_name))
553+
554+
batch = BatchStatement(BatchType.LOGGED)
555+
556+
batch.add("""INSERT INTO {0}.users (user_id, first, last, age)
557+
VALUES (%(a)s, %(b)s, %(c)s, %(d)s)
558+
""".format(self.keyspace_name),
559+
{'a': 0, 'b': 'John', 'c': 'Doe', 'd': 40})
560+
561+
batch.add("""INSERT INTO {0}.users (user_id, first, last, age)
562+
VALUES (%(a)s, %(b)s, %(c)s, %(d)s)
563+
""".format(self.keyspace_name),
564+
{'a': 1, 'b': 'Jane', 'c': 'Doe', 'd': 30})
565+
566+
self.session.execute(batch)
567+
568+
result = self.session.execute("SELECT * FROM {0}.users".format(self.keyspace_name))
569+
self.assertEqual(result[0].user_id, 0)
570+
self.assertEqual(result[0].first, 'John')
571+
self.assertEqual(result[0].last, 'Doe')
572+
self.assertEqual(result[0].age, 40)
573+
574+
self.assertEqual(result[1].user_id, 1)
575+
self.assertEqual(result[1].first, 'Jane')
576+
self.assertEqual(result[1].last, 'Doe')
577+
self.assertEqual(result[1].age, 30)
578+
441579

442580
class SerialConsistencyTests(unittest.TestCase):
443581
def setUp(self):

0 commit comments

Comments
 (0)