Skip to content

Commit c0b1867

Browse files
committed
Merge pull request apache#423 from datastax/178
PYTHON-178 - Make bind ignore extra keys in dict values
2 parents 6b33173 + 55ebfdc commit c0b1867

3 files changed

Lines changed: 16 additions & 15 deletions

File tree

cassandra/query.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -486,23 +486,24 @@ def bind(self, values):
486486
* short sequences will be extended to match bind parameters with UNSET_VALUE
487487
* names may be omitted from a dict with UNSET_VALUE implied.
488488
489+
.. versionchanged:: 3.0.0
490+
491+
method will not throw if extra keys are present in bound dict (PYTHON-178)
489492
"""
490493
if values is None:
491494
values = ()
492495
proto_version = self.prepared_statement.protocol_version
493496
col_meta = self.prepared_statement.column_metadata
494-
col_meta_len = len(col_meta)
495-
value_len = len(values)
496497

497498
# special case for binding dicts
498499
if isinstance(values, dict):
499-
unbound_values = values.copy()
500+
values_dict = values
500501
values = []
501502

502503
# sort values accordingly
503504
for col in col_meta:
504505
try:
505-
values.append(unbound_values.pop(col.name))
506+
values.append(values_dict[col.name])
506507
except KeyError:
507508
if proto_version >= 4:
508509
values.append(UNSET_VALUE)
@@ -511,10 +512,8 @@ def bind(self, values):
511512
'Column name `%s` not found in bound dict.' %
512513
(col.name))
513514

514-
value_len = len(values)
515-
516-
if unbound_values:
517-
raise ValueError("Unexpected arguments provided to bind(): %s" % unbound_values.keys())
515+
value_len = len(values)
516+
col_meta_len = len(col_meta)
518517

519518
if value_len > col_meta_len:
520519
raise ValueError(

tests/integration/standard/test_prepared_statements.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ def _run_too_many_bind_values(self, session):
173173
self.assertIsInstance(prepared, PreparedStatement)
174174
self.assertRaises(ValueError, prepared.bind, (1, 2))
175175

176-
def test_too_many_bind_values_dicts(self):
176+
def test_imprecise_bind_values_dicts(self):
177177
"""
178178
Ensure an error is thrown when attempting to bind the wrong values
179179
with dict bindings
@@ -189,16 +189,16 @@ def test_too_many_bind_values_dicts(self):
189189

190190
self.assertIsInstance(prepared, PreparedStatement)
191191

192-
# too many values
193-
self.assertRaises(ValueError, prepared.bind, {'k': 1, 'v': 2, 'v2': 3})
192+
# too many values is ok - others are ignored
193+
prepared.bind({'k': 1, 'v': 2, 'v2': 3})
194194

195195
# right number, but one does not belong
196196
if PROTOCOL_VERSION < 4:
197197
# pre v4, the driver bails with key error when 'v' is found missing
198198
self.assertRaises(KeyError, prepared.bind, {'k': 1, 'v2': 3})
199199
else:
200-
# post v4, the driver uses UNSET_VALUE for 'v' and bails when 'v2' is unbound
201-
self.assertRaises(ValueError, prepared.bind, {'k': 1, 'v2': 3})
200+
# post v4, the driver uses UNSET_VALUE for 'v' and 'v2' is ignored
201+
prepared.bind({'k': 1, 'v2': 3})
202202

203203
# also catch too few variables with dicts
204204
self.assertIsInstance(prepared, PreparedStatement)

tests/unit/test_parameter_binding.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
from cassandra.util import OrderedDict
2626

2727
from six.moves import xrange
28+
import six
2829

2930

3031
class ParamBindingTest(unittest.TestCase):
@@ -147,8 +148,9 @@ def test_dict_missing_routing_key(self):
147148
def test_missing_value(self):
148149
self.assertRaises(KeyError, self.bound.bind, {'rk0': 0, 'rk1': 0, 'ck0': 0})
149150

150-
def test_dict_extra_value(self):
151-
self.assertRaises(ValueError, self.bound.bind, {'rk0': 0, 'rk1': 0, 'ck0': 0, 'v0': 0, 'should_not_be_here': 123})
151+
def test_extra_value(self):
152+
self.bound.bind({'rk0': 0, 'rk1': 0, 'ck0': 0, 'v0': 0, 'should_not_be_here': 123}) # okay to have extra keys in dict
153+
self.assertEqual(self.bound.values, [six.b('\x00') * 4] * 4) # four encoded zeros
152154
self.assertRaises(ValueError, self.bound.bind, (0, 0, 0, 0, 123))
153155

154156
def test_values_none(self):

0 commit comments

Comments
 (0)