Author: cito
Date: Thu Jul 21 12:57:25 2016
New Revision: 878
Log:
Allow extra keys in params to query_formatted()
Modified:
trunk/docs/contents/changelog.rst
trunk/pg.py
trunk/tests/test_classic_dbwrapper.py
Modified: trunk/docs/contents/changelog.rst
==============================================================================
--- trunk/docs/contents/changelog.rst Sat Jul 16 05:36:09 2016 (r877)
+++ trunk/docs/contents/changelog.rst Thu Jul 21 12:57:25 2016 (r878)
@@ -13,6 +13,8 @@
old versions of PostgreSQL are not officially supported and tested any more.
- Fixed an issue with Postgres types that have an OID >= 0x80000000 (reported
on the mailing list by Justin Pryzby).
+- Allow extra values that are not used in the command in the parameter dict
+ passed to the query_formatted() method (as suggested by Justin Pryzby).
- Made C extension compatible with MSVC 9 again (this was needed to compile for
Python 2 on Windows).
Modified: trunk/pg.py
==============================================================================
--- trunk/pg.py Sat Jul 16 05:36:09 2016 (r877)
+++ trunk/pg.py Thu Jul 21 12:57:25 2016 (r878)
@@ -619,8 +619,20 @@
else:
for value in values:
append(add(value))
- command = command % tuple(literals)
+ command %= tuple(literals)
elif isinstance(values, dict):
+ # we want to allow extra keys in the dictionary,
+ # so we first must find the values actually used in the command
+ used_values = {}
+ literals = dict.fromkeys(values, '')
+ for key in literals:
+ del literals[key]
+ try:
+ command % literals
+ except KeyError:
+ used_values[key] = values[key]
+ literals[key] = ''
+ values = used_values
if inline:
adapt = self.adapt_inline
literals = dict((key, adapt(value))
@@ -629,15 +641,14 @@
add = params.add
literals = {}
if types:
- if (not isinstance(types, dict) or
- len(types) < len(values)):
+ if not isinstance(types, dict):
raise TypeError('The values and types do not match')
for key in sorted(values):
- literals[key] = add(values[key], types[key])
+ literals[key] = add(values[key], types.get(key))
else:
for key in sorted(values):
literals[key] = add(values[key])
- command = command % literals
+ command %= literals
else:
raise TypeError('The values must be passed as tuple, list or dict')
return command, params
Modified: trunk/tests/test_classic_dbwrapper.py
==============================================================================
--- trunk/tests/test_classic_dbwrapper.py Sat Jul 16 05:36:09 2016
(r877)
+++ trunk/tests/test_classic_dbwrapper.py Thu Jul 21 12:57:25 2016
(r878)
@@ -893,10 +893,12 @@
def testQueryFormatted(self):
f = self.db.query_formatted
t = True if pg.get_bool() else 't'
+ # test with tuple
q = f("select %s::int, %s::real, %s::text, %s::bool",
(3, 2.5, 'hello', True))
r = q.getresult()[0]
self.assertEqual(r, (3, 2.5, 'hello', t))
+ # test with tuple, inline
q = f("select %s, %s, %s, %s", (3, 2.5, 'hello', True), inline=True)
r = q.getresult()[0]
if isinstance(r[1], Decimal):
@@ -905,6 +907,28 @@
r[1] = float(r[1])
r = tuple(r)
self.assertEqual(r, (3, 2.5, 'hello', t))
+ # test with dict
+ q = f("select %(a)s::int, %(b)s::real, %(c)s::text, %(d)s::bool",
+ dict(a=3, b=2.5, c='hello', d=True))
+ r = q.getresult()[0]
+ self.assertEqual(r, (3, 2.5, 'hello', t))
+ # test with dict, inline
+ q = f("select %(a)s, %(b)s, %(c)s, %(d)s",
+ dict(a=3, b=2.5, c='hello', d=True), inline=True)
+ r = q.getresult()[0]
+ if isinstance(r[1], Decimal):
+ # Python 2.6 cannot compare float and Decimal
+ r = list(r)
+ r[1] = float(r[1])
+ r = tuple(r)
+ self.assertEqual(r, (3, 2.5, 'hello', t))
+ # test with dict and extra values
+ q = f("select %(a)s||%(b)s||%(c)s||%(d)s||'epsilon'",
+ dict(a='alpha', b='beta', c='gamma', d='delta', e='extra'))
+ r = q.getresult()[0][0]
+ self.assertEqual(r, 'alphabetagammadeltaepsilon')
+
+
def testPkey(self):
query = self.db.query
_______________________________________________
PyGreSQL mailing list
[email protected]
https://mail.vex.net/mailman/listinfo.cgi/pygresql