2007-11-11 13:40:12 +03:00
|
|
|
#!/usr/bin/env python
|
2010-02-13 01:34:53 +03:00
|
|
|
#
|
2005-01-13 19:50:29 +03:00
|
|
|
# extras_dictcursor - test if DictCursor extension class works
|
|
|
|
#
|
2010-02-13 01:34:53 +03:00
|
|
|
# Copyright (C) 2004-2010 Federico Di Gregorio <fog@debian.org>
|
2005-01-13 19:50:29 +03:00
|
|
|
#
|
2010-02-13 01:34:53 +03:00
|
|
|
# psycopg2 is free software: you can redistribute it and/or modify it
|
|
|
|
# under the terms of the GNU Lesser General Public License as published
|
|
|
|
# by the Free Software Foundation, either version 3 of the License, or
|
|
|
|
# (at your option) any later version.
|
2005-01-13 19:50:29 +03:00
|
|
|
#
|
2010-02-13 01:34:53 +03:00
|
|
|
# psycopg2 is distributed in the hope that it will be useful, but WITHOUT
|
|
|
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
|
|
|
# License for more details.
|
2005-01-13 19:50:29 +03:00
|
|
|
|
2011-04-26 22:26:19 +04:00
|
|
|
import time
|
|
|
|
from datetime import timedelta
|
2005-07-17 08:26:27 +04:00
|
|
|
import psycopg2
|
|
|
|
import psycopg2.extras
|
2017-12-02 04:59:53 +03:00
|
|
|
import unittest
|
2018-05-21 01:36:03 +03:00
|
|
|
from .testutils import ConnectingTestCase, skip_before_postgres, \
|
|
|
|
skip_before_python, skip_from_python
|
2005-01-13 19:50:29 +03:00
|
|
|
|
2007-11-11 13:40:12 +03:00
|
|
|
|
2018-05-21 01:35:26 +03:00
|
|
|
class _DictCursorBase(ConnectingTestCase):
|
2005-01-13 19:50:29 +03:00
|
|
|
def setUp(self):
|
2013-04-07 03:23:30 +04:00
|
|
|
ConnectingTestCase.setUp(self)
|
2005-01-13 19:50:29 +03:00
|
|
|
curs = self.conn.cursor()
|
2007-11-11 13:40:12 +03:00
|
|
|
curs.execute("CREATE TEMPORARY TABLE ExtrasDictCursorTests (foo text)")
|
2009-03-02 12:59:52 +03:00
|
|
|
curs.execute("INSERT INTO ExtrasDictCursorTests VALUES ('bar')")
|
|
|
|
self.conn.commit()
|
2007-11-11 13:40:12 +03:00
|
|
|
|
2018-05-21 01:35:26 +03:00
|
|
|
def _testIterRowNumber(self, curs):
|
|
|
|
# Only checking for dataset < itersize:
|
|
|
|
# see CursorTests.test_iter_named_cursor_rownumber
|
|
|
|
curs.itersize = 20
|
|
|
|
curs.execute("""select * from generate_series(1,10)""")
|
|
|
|
for i, r in enumerate(curs):
|
|
|
|
self.assertEqual(i + 1, curs.rownumber)
|
|
|
|
|
|
|
|
def _testNamedCursorNotGreedy(self, curs):
|
|
|
|
curs.itersize = 2
|
|
|
|
curs.execute("""select clock_timestamp() as ts from generate_series(1,3)""")
|
|
|
|
recs = []
|
|
|
|
for t in curs:
|
|
|
|
time.sleep(0.01)
|
|
|
|
recs.append(t)
|
|
|
|
|
|
|
|
# check that the dataset was not fetched in a single gulp
|
|
|
|
self.assert_(recs[1]['ts'] - recs[0]['ts'] < timedelta(seconds=0.005))
|
|
|
|
self.assert_(recs[2]['ts'] - recs[1]['ts'] > timedelta(seconds=0.0099))
|
|
|
|
|
|
|
|
|
|
|
|
class ExtrasDictCursorTests(_DictCursorBase):
|
|
|
|
"""Test if DictCursor extension class works."""
|
|
|
|
|
2012-04-11 21:00:18 +04:00
|
|
|
def testDictConnCursorArgs(self):
|
|
|
|
self.conn.close()
|
2013-04-07 03:23:30 +04:00
|
|
|
self.conn = self.connect(connection_factory=psycopg2.extras.DictConnection)
|
2012-04-11 21:00:18 +04:00
|
|
|
cur = self.conn.cursor()
|
|
|
|
self.assert_(isinstance(cur, psycopg2.extras.DictCursor))
|
|
|
|
self.assertEqual(cur.name, None)
|
|
|
|
# overridable
|
2016-10-11 02:10:53 +03:00
|
|
|
cur = self.conn.cursor('foo',
|
|
|
|
cursor_factory=psycopg2.extras.NamedTupleCursor)
|
2012-04-11 21:00:18 +04:00
|
|
|
self.assertEqual(cur.name, 'foo')
|
|
|
|
self.assert_(isinstance(cur, psycopg2.extras.NamedTupleCursor))
|
2012-02-24 01:27:45 +04:00
|
|
|
|
2009-03-02 12:59:52 +03:00
|
|
|
def testDictCursorWithPlainCursorFetchOne(self):
|
|
|
|
self._testWithPlainCursor(lambda curs: curs.fetchone())
|
|
|
|
|
|
|
|
def testDictCursorWithPlainCursorFetchMany(self):
|
|
|
|
self._testWithPlainCursor(lambda curs: curs.fetchmany(100)[0])
|
|
|
|
|
2012-01-10 05:27:43 +04:00
|
|
|
def testDictCursorWithPlainCursorFetchManyNoarg(self):
|
|
|
|
self._testWithPlainCursor(lambda curs: curs.fetchmany()[0])
|
|
|
|
|
2009-03-02 12:59:52 +03:00
|
|
|
def testDictCursorWithPlainCursorFetchAll(self):
|
|
|
|
self._testWithPlainCursor(lambda curs: curs.fetchall()[0])
|
|
|
|
|
|
|
|
def testDictCursorWithPlainCursorIter(self):
|
|
|
|
def getter(curs):
|
|
|
|
for row in curs:
|
|
|
|
return row
|
|
|
|
self._testWithPlainCursor(getter)
|
2009-05-09 16:44:59 +04:00
|
|
|
|
2012-02-24 01:27:45 +04:00
|
|
|
def testUpdateRow(self):
|
|
|
|
row = self._testWithPlainCursor(lambda curs: curs.fetchone())
|
|
|
|
row['foo'] = 'qux'
|
|
|
|
self.failUnless(row['foo'] == 'qux')
|
|
|
|
self.failUnless(row[0] == 'qux')
|
|
|
|
|
2012-02-24 02:55:13 +04:00
|
|
|
@skip_before_postgres(8, 0)
|
|
|
|
def testDictCursorWithPlainCursorIterRowNumber(self):
|
|
|
|
curs = self.conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
|
|
|
|
self._testIterRowNumber(curs)
|
|
|
|
|
2012-02-24 01:27:45 +04:00
|
|
|
def _testWithPlainCursor(self, getter):
|
|
|
|
curs = self.conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
|
|
|
|
curs.execute("SELECT * FROM ExtrasDictCursorTests")
|
|
|
|
row = getter(curs)
|
|
|
|
self.failUnless(row['foo'] == 'bar')
|
|
|
|
self.failUnless(row[0] == 'bar')
|
|
|
|
return row
|
|
|
|
|
2009-03-02 12:59:52 +03:00
|
|
|
def testDictCursorWithNamedCursorFetchOne(self):
|
|
|
|
self._testWithNamedCursor(lambda curs: curs.fetchone())
|
|
|
|
|
|
|
|
def testDictCursorWithNamedCursorFetchMany(self):
|
|
|
|
self._testWithNamedCursor(lambda curs: curs.fetchmany(100)[0])
|
|
|
|
|
2012-01-10 05:27:43 +04:00
|
|
|
def testDictCursorWithNamedCursorFetchManyNoarg(self):
|
|
|
|
self._testWithNamedCursor(lambda curs: curs.fetchmany()[0])
|
|
|
|
|
2009-03-02 12:59:52 +03:00
|
|
|
def testDictCursorWithNamedCursorFetchAll(self):
|
|
|
|
self._testWithNamedCursor(lambda curs: curs.fetchall()[0])
|
|
|
|
|
|
|
|
def testDictCursorWithNamedCursorIter(self):
|
|
|
|
def getter(curs):
|
|
|
|
for row in curs:
|
|
|
|
return row
|
|
|
|
self._testWithNamedCursor(getter)
|
|
|
|
|
2011-12-12 02:04:42 +04:00
|
|
|
@skip_before_postgres(8, 2)
|
|
|
|
def testDictCursorWithNamedCursorNotGreedy(self):
|
|
|
|
curs = self.conn.cursor('tmp', cursor_factory=psycopg2.extras.DictCursor)
|
|
|
|
self._testNamedCursorNotGreedy(curs)
|
|
|
|
|
2012-02-24 02:55:13 +04:00
|
|
|
@skip_before_postgres(8, 0)
|
|
|
|
def testDictCursorWithNamedCursorIterRowNumber(self):
|
|
|
|
curs = self.conn.cursor('tmp', cursor_factory=psycopg2.extras.DictCursor)
|
|
|
|
self._testIterRowNumber(curs)
|
|
|
|
|
2012-02-24 01:27:45 +04:00
|
|
|
def _testWithNamedCursor(self, getter):
|
|
|
|
curs = self.conn.cursor('aname', cursor_factory=psycopg2.extras.DictCursor)
|
|
|
|
curs.execute("SELECT * FROM ExtrasDictCursorTests")
|
|
|
|
row = getter(curs)
|
|
|
|
self.failUnless(row['foo'] == 'bar')
|
|
|
|
self.failUnless(row[0] == 'bar')
|
|
|
|
|
2018-05-21 01:35:26 +03:00
|
|
|
def testPickleDictRow(self):
|
|
|
|
import pickle
|
|
|
|
curs = self.conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
|
|
|
|
curs.execute("select 10 as a, 20 as b")
|
|
|
|
r = curs.fetchone()
|
|
|
|
d = pickle.dumps(r)
|
|
|
|
r1 = pickle.loads(d)
|
|
|
|
self.assertEqual(r, r1)
|
|
|
|
self.assertEqual(r[0], r1[0])
|
|
|
|
self.assertEqual(r[1], r1[1])
|
|
|
|
self.assertEqual(r['a'], r1['a'])
|
|
|
|
self.assertEqual(r['b'], r1['b'])
|
|
|
|
self.assertEqual(r._index, r1._index)
|
|
|
|
|
2018-05-21 01:36:03 +03:00
|
|
|
@skip_from_python(3)
|
|
|
|
def test_iter_methods_2(self):
|
|
|
|
curs = self.conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
|
|
|
|
curs.execute("select 10 as a, 20 as b")
|
|
|
|
r = curs.fetchone()
|
|
|
|
self.assert_(isinstance(r.keys(), list))
|
|
|
|
self.assertEqual(len(r.keys()), 2)
|
|
|
|
self.assert_(isinstance(r.values(), tuple)) # sic?
|
|
|
|
self.assertEqual(len(r.values()), 2)
|
|
|
|
self.assert_(isinstance(r.items(), list))
|
|
|
|
self.assertEqual(len(r.items()), 2)
|
|
|
|
|
|
|
|
self.assert_(not isinstance(r.iterkeys(), list))
|
|
|
|
self.assertEqual(len(list(r.iterkeys())), 2)
|
|
|
|
self.assert_(not isinstance(r.itervalues(), list))
|
|
|
|
self.assertEqual(len(list(r.itervalues())), 2)
|
|
|
|
self.assert_(not isinstance(r.iteritems(), list))
|
|
|
|
self.assertEqual(len(list(r.iteritems())), 2)
|
|
|
|
|
|
|
|
@skip_before_python(3)
|
|
|
|
def test_iter_methods_3(self):
|
|
|
|
curs = self.conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
|
|
|
|
curs.execute("select 10 as a, 20 as b")
|
|
|
|
r = curs.fetchone()
|
|
|
|
self.assert_(not isinstance(r.keys(), list))
|
|
|
|
self.assertEqual(len(list(r.keys())), 2)
|
|
|
|
self.assert_(not isinstance(r.values(), list))
|
|
|
|
self.assertEqual(len(list(r.values())), 2)
|
|
|
|
self.assert_(not isinstance(r.items(), list))
|
|
|
|
self.assertEqual(len(list(r.items())), 2)
|
|
|
|
|
2018-05-21 01:35:26 +03:00
|
|
|
|
|
|
|
class ExtrasDictCursorRealTests(_DictCursorBase):
|
|
|
|
def testDictCursorWithPlainCursorRealFetchOne(self):
|
|
|
|
self._testWithPlainCursorReal(lambda curs: curs.fetchone())
|
|
|
|
|
|
|
|
def testDictCursorWithPlainCursorRealFetchMany(self):
|
|
|
|
self._testWithPlainCursorReal(lambda curs: curs.fetchmany(100)[0])
|
|
|
|
|
|
|
|
def testDictCursorWithPlainCursorRealFetchManyNoarg(self):
|
|
|
|
self._testWithPlainCursorReal(lambda curs: curs.fetchmany()[0])
|
|
|
|
|
|
|
|
def testDictCursorWithPlainCursorRealFetchAll(self):
|
|
|
|
self._testWithPlainCursorReal(lambda curs: curs.fetchall()[0])
|
|
|
|
|
|
|
|
def testDictCursorWithPlainCursorRealIter(self):
|
|
|
|
def getter(curs):
|
|
|
|
for row in curs:
|
|
|
|
return row
|
|
|
|
self._testWithPlainCursorReal(getter)
|
|
|
|
|
|
|
|
@skip_before_postgres(8, 0)
|
|
|
|
def testDictCursorWithPlainCursorRealIterRowNumber(self):
|
|
|
|
curs = self.conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor)
|
|
|
|
self._testIterRowNumber(curs)
|
|
|
|
|
|
|
|
def _testWithPlainCursorReal(self, getter):
|
|
|
|
curs = self.conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor)
|
|
|
|
curs.execute("SELECT * FROM ExtrasDictCursorTests")
|
|
|
|
row = getter(curs)
|
|
|
|
self.failUnless(row['foo'] == 'bar')
|
|
|
|
|
|
|
|
def testPickleRealDictRow(self):
|
|
|
|
import pickle
|
|
|
|
curs = self.conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor)
|
|
|
|
curs.execute("select 10 as a, 20 as b")
|
|
|
|
r = curs.fetchone()
|
|
|
|
d = pickle.dumps(r)
|
|
|
|
r1 = pickle.loads(d)
|
|
|
|
self.assertEqual(r, r1)
|
|
|
|
self.assertEqual(r['a'], r1['a'])
|
|
|
|
self.assertEqual(r['b'], r1['b'])
|
|
|
|
self.assertEqual(r._column_mapping, r1._column_mapping)
|
|
|
|
|
2011-09-12 05:20:53 +04:00
|
|
|
def testDictCursorRealWithNamedCursorFetchOne(self):
|
|
|
|
self._testWithNamedCursorReal(lambda curs: curs.fetchone())
|
|
|
|
|
|
|
|
def testDictCursorRealWithNamedCursorFetchMany(self):
|
|
|
|
self._testWithNamedCursorReal(lambda curs: curs.fetchmany(100)[0])
|
|
|
|
|
2012-01-10 05:27:43 +04:00
|
|
|
def testDictCursorRealWithNamedCursorFetchManyNoarg(self):
|
|
|
|
self._testWithNamedCursorReal(lambda curs: curs.fetchmany()[0])
|
|
|
|
|
2011-09-12 05:20:53 +04:00
|
|
|
def testDictCursorRealWithNamedCursorFetchAll(self):
|
|
|
|
self._testWithNamedCursorReal(lambda curs: curs.fetchall()[0])
|
|
|
|
|
|
|
|
def testDictCursorRealWithNamedCursorIter(self):
|
|
|
|
def getter(curs):
|
|
|
|
for row in curs:
|
|
|
|
return row
|
|
|
|
self._testWithNamedCursorReal(getter)
|
|
|
|
|
2011-12-12 02:04:42 +04:00
|
|
|
@skip_before_postgres(8, 2)
|
|
|
|
def testDictCursorRealWithNamedCursorNotGreedy(self):
|
|
|
|
curs = self.conn.cursor('tmp', cursor_factory=psycopg2.extras.RealDictCursor)
|
|
|
|
self._testNamedCursorNotGreedy(curs)
|
|
|
|
|
2012-02-24 02:55:13 +04:00
|
|
|
@skip_before_postgres(8, 0)
|
|
|
|
def testDictCursorRealWithNamedCursorIterRowNumber(self):
|
|
|
|
curs = self.conn.cursor('tmp', cursor_factory=psycopg2.extras.RealDictCursor)
|
|
|
|
self._testIterRowNumber(curs)
|
|
|
|
|
2009-05-09 16:44:59 +04:00
|
|
|
def _testWithNamedCursorReal(self, getter):
|
2016-10-11 02:10:53 +03:00
|
|
|
curs = self.conn.cursor('aname',
|
|
|
|
cursor_factory=psycopg2.extras.RealDictCursor)
|
2009-05-09 16:44:59 +04:00
|
|
|
curs.execute("SELECT * FROM ExtrasDictCursorTests")
|
|
|
|
row = getter(curs)
|
|
|
|
self.failUnless(row['foo'] == 'bar')
|
|
|
|
|
2018-05-21 01:36:03 +03:00
|
|
|
@skip_from_python(3)
|
|
|
|
def test_iter_methods_2(self):
|
|
|
|
curs = self.conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor)
|
|
|
|
curs.execute("select 10 as a, 20 as b")
|
|
|
|
r = curs.fetchone()
|
|
|
|
self.assert_(isinstance(r.keys(), list))
|
|
|
|
self.assertEqual(len(r.keys()), 2)
|
|
|
|
self.assert_(isinstance(r.values(), list))
|
|
|
|
self.assertEqual(len(r.values()), 2)
|
|
|
|
self.assert_(isinstance(r.items(), list))
|
|
|
|
self.assertEqual(len(r.items()), 2)
|
|
|
|
|
|
|
|
self.assert_(not isinstance(r.iterkeys(), list))
|
|
|
|
self.assertEqual(len(list(r.iterkeys())), 2)
|
|
|
|
self.assert_(not isinstance(r.itervalues(), list))
|
|
|
|
self.assertEqual(len(list(r.itervalues())), 2)
|
|
|
|
self.assert_(not isinstance(r.iteritems(), list))
|
|
|
|
self.assertEqual(len(list(r.iteritems())), 2)
|
|
|
|
|
|
|
|
@skip_before_python(3)
|
|
|
|
def test_iter_methods_3(self):
|
|
|
|
curs = self.conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor)
|
|
|
|
curs.execute("select 10 as a, 20 as b")
|
|
|
|
r = curs.fetchone()
|
|
|
|
self.assert_(not isinstance(r.keys(), list))
|
|
|
|
self.assertEqual(len(list(r.keys())), 2)
|
|
|
|
self.assert_(not isinstance(r.values(), list))
|
|
|
|
self.assertEqual(len(list(r.values())), 2)
|
|
|
|
self.assert_(not isinstance(r.items(), list))
|
|
|
|
self.assertEqual(len(list(r.items())), 2)
|
|
|
|
|
2010-11-06 04:39:43 +03:00
|
|
|
|
2013-04-07 03:23:30 +04:00
|
|
|
class NamedTupleCursorTest(ConnectingTestCase):
|
2010-11-06 04:39:43 +03:00
|
|
|
def setUp(self):
|
2013-04-07 03:23:30 +04:00
|
|
|
ConnectingTestCase.setUp(self)
|
2010-11-06 04:39:43 +03:00
|
|
|
from psycopg2.extras import NamedTupleConnection
|
|
|
|
|
2013-04-07 03:23:30 +04:00
|
|
|
self.conn = self.connect(connection_factory=NamedTupleConnection)
|
2010-11-06 04:39:43 +03:00
|
|
|
curs = self.conn.cursor()
|
|
|
|
curs.execute("CREATE TEMPORARY TABLE nttest (i int, s text)")
|
2010-11-19 06:55:37 +03:00
|
|
|
curs.execute("INSERT INTO nttest VALUES (1, 'foo')")
|
|
|
|
curs.execute("INSERT INTO nttest VALUES (2, 'bar')")
|
|
|
|
curs.execute("INSERT INTO nttest VALUES (3, 'baz')")
|
2010-11-06 04:39:43 +03:00
|
|
|
self.conn.commit()
|
|
|
|
|
2012-04-11 21:00:18 +04:00
|
|
|
def test_cursor_args(self):
|
|
|
|
cur = self.conn.cursor('foo', cursor_factory=psycopg2.extras.DictCursor)
|
|
|
|
self.assertEqual(cur.name, 'foo')
|
|
|
|
self.assert_(isinstance(cur, psycopg2.extras.DictCursor))
|
|
|
|
|
2010-11-06 04:39:43 +03:00
|
|
|
def test_fetchone(self):
|
|
|
|
curs = self.conn.cursor()
|
2012-02-24 02:58:58 +04:00
|
|
|
curs.execute("select * from nttest order by 1")
|
2010-11-06 04:39:43 +03:00
|
|
|
t = curs.fetchone()
|
|
|
|
self.assertEqual(t[0], 1)
|
|
|
|
self.assertEqual(t.i, 1)
|
|
|
|
self.assertEqual(t[1], 'foo')
|
|
|
|
self.assertEqual(t.s, 'foo')
|
2012-02-24 02:58:58 +04:00
|
|
|
self.assertEqual(curs.rownumber, 1)
|
|
|
|
self.assertEqual(curs.rowcount, 3)
|
2010-11-06 04:39:43 +03:00
|
|
|
|
2012-01-10 05:27:43 +04:00
|
|
|
def test_fetchmany_noarg(self):
|
|
|
|
curs = self.conn.cursor()
|
|
|
|
curs.arraysize = 2
|
|
|
|
curs.execute("select * from nttest order by 1")
|
|
|
|
res = curs.fetchmany()
|
|
|
|
self.assertEqual(2, len(res))
|
|
|
|
self.assertEqual(res[0].i, 1)
|
|
|
|
self.assertEqual(res[0].s, 'foo')
|
|
|
|
self.assertEqual(res[1].i, 2)
|
|
|
|
self.assertEqual(res[1].s, 'bar')
|
2012-02-24 02:58:58 +04:00
|
|
|
self.assertEqual(curs.rownumber, 2)
|
|
|
|
self.assertEqual(curs.rowcount, 3)
|
2012-01-10 05:27:43 +04:00
|
|
|
|
2010-11-06 04:39:43 +03:00
|
|
|
def test_fetchmany(self):
|
|
|
|
curs = self.conn.cursor()
|
|
|
|
curs.execute("select * from nttest order by 1")
|
|
|
|
res = curs.fetchmany(2)
|
|
|
|
self.assertEqual(2, len(res))
|
|
|
|
self.assertEqual(res[0].i, 1)
|
|
|
|
self.assertEqual(res[0].s, 'foo')
|
|
|
|
self.assertEqual(res[1].i, 2)
|
|
|
|
self.assertEqual(res[1].s, 'bar')
|
2012-02-24 02:58:58 +04:00
|
|
|
self.assertEqual(curs.rownumber, 2)
|
|
|
|
self.assertEqual(curs.rowcount, 3)
|
2010-11-06 04:39:43 +03:00
|
|
|
|
|
|
|
def test_fetchall(self):
|
|
|
|
curs = self.conn.cursor()
|
|
|
|
curs.execute("select * from nttest order by 1")
|
|
|
|
res = curs.fetchall()
|
|
|
|
self.assertEqual(3, len(res))
|
|
|
|
self.assertEqual(res[0].i, 1)
|
|
|
|
self.assertEqual(res[0].s, 'foo')
|
|
|
|
self.assertEqual(res[1].i, 2)
|
|
|
|
self.assertEqual(res[1].s, 'bar')
|
|
|
|
self.assertEqual(res[2].i, 3)
|
|
|
|
self.assertEqual(res[2].s, 'baz')
|
2012-02-24 02:58:58 +04:00
|
|
|
self.assertEqual(curs.rownumber, 3)
|
|
|
|
self.assertEqual(curs.rowcount, 3)
|
2010-11-06 04:39:43 +03:00
|
|
|
|
2011-08-09 14:29:15 +04:00
|
|
|
def test_executemany(self):
|
|
|
|
curs = self.conn.cursor()
|
|
|
|
curs.executemany("delete from nttest where i = %s",
|
|
|
|
[(1,), (2,)])
|
|
|
|
curs.execute("select * from nttest order by 1")
|
|
|
|
res = curs.fetchall()
|
|
|
|
self.assertEqual(1, len(res))
|
|
|
|
self.assertEqual(res[0].i, 3)
|
|
|
|
self.assertEqual(res[0].s, 'baz')
|
|
|
|
|
2010-11-06 04:39:43 +03:00
|
|
|
def test_iter(self):
|
|
|
|
curs = self.conn.cursor()
|
|
|
|
curs.execute("select * from nttest order by 1")
|
|
|
|
i = iter(curs)
|
2012-02-24 02:58:58 +04:00
|
|
|
self.assertEqual(curs.rownumber, 0)
|
|
|
|
|
2017-12-02 06:53:30 +03:00
|
|
|
t = next(i)
|
2010-11-06 04:39:43 +03:00
|
|
|
self.assertEqual(t.i, 1)
|
|
|
|
self.assertEqual(t.s, 'foo')
|
2012-02-24 02:58:58 +04:00
|
|
|
self.assertEqual(curs.rownumber, 1)
|
|
|
|
self.assertEqual(curs.rowcount, 3)
|
|
|
|
|
2017-12-02 06:53:30 +03:00
|
|
|
t = next(i)
|
2010-11-06 04:39:43 +03:00
|
|
|
self.assertEqual(t.i, 2)
|
|
|
|
self.assertEqual(t.s, 'bar')
|
2012-02-24 02:58:58 +04:00
|
|
|
self.assertEqual(curs.rownumber, 2)
|
|
|
|
self.assertEqual(curs.rowcount, 3)
|
|
|
|
|
2017-12-02 06:53:30 +03:00
|
|
|
t = next(i)
|
2010-11-06 04:39:43 +03:00
|
|
|
self.assertEqual(t.i, 3)
|
|
|
|
self.assertEqual(t.s, 'baz')
|
2017-12-02 06:53:30 +03:00
|
|
|
self.assertRaises(StopIteration, next, i)
|
2012-02-24 02:58:58 +04:00
|
|
|
self.assertEqual(curs.rownumber, 3)
|
|
|
|
self.assertEqual(curs.rowcount, 3)
|
2010-11-06 04:39:43 +03:00
|
|
|
|
2010-11-11 13:26:36 +03:00
|
|
|
def test_record_updated(self):
|
|
|
|
curs = self.conn.cursor()
|
|
|
|
curs.execute("select 1 as foo;")
|
|
|
|
r = curs.fetchone()
|
|
|
|
self.assertEqual(r.foo, 1)
|
|
|
|
|
|
|
|
curs.execute("select 2 as bar;")
|
|
|
|
r = curs.fetchone()
|
|
|
|
self.assertEqual(r.bar, 2)
|
|
|
|
self.assertRaises(AttributeError, getattr, r, 'foo')
|
|
|
|
|
2010-11-11 13:30:01 +03:00
|
|
|
def test_no_result_no_surprise(self):
|
|
|
|
curs = self.conn.cursor()
|
|
|
|
curs.execute("update nttest set s = s")
|
|
|
|
self.assertRaises(psycopg2.ProgrammingError, curs.fetchone)
|
|
|
|
|
|
|
|
curs.execute("update nttest set s = s")
|
|
|
|
self.assertRaises(psycopg2.ProgrammingError, curs.fetchall)
|
|
|
|
|
2018-01-29 05:41:44 +03:00
|
|
|
def test_bad_col_names(self):
|
|
|
|
curs = self.conn.cursor()
|
|
|
|
curs.execute('select 1 as "foo.bar_baz", 2 as "?column?", 3 as "3"')
|
|
|
|
rv = curs.fetchone()
|
|
|
|
self.assertEqual(rv.foo_bar_baz, 1)
|
|
|
|
self.assertEqual(rv.f_column_, 2)
|
|
|
|
self.assertEqual(rv.f3, 3)
|
|
|
|
|
2018-05-14 01:51:21 +03:00
|
|
|
@skip_before_python(3)
|
2018-05-14 05:11:11 +03:00
|
|
|
@skip_before_postgres(8)
|
2018-05-14 01:51:21 +03:00
|
|
|
def test_nonascii_name(self):
|
|
|
|
curs = self.conn.cursor()
|
|
|
|
curs.execute('select 1 as \xe5h\xe9')
|
|
|
|
rv = curs.fetchone()
|
|
|
|
self.assertEqual(getattr(rv, '\xe5h\xe9'), 1)
|
|
|
|
|
2010-11-11 13:26:36 +03:00
|
|
|
def test_minimal_generation(self):
|
|
|
|
# Instrument the class to verify it gets called the minimum number of times.
|
|
|
|
from psycopg2.extras import NamedTupleCursor
|
|
|
|
f_orig = NamedTupleCursor._make_nt
|
|
|
|
calls = [0]
|
2016-10-11 02:10:53 +03:00
|
|
|
|
2010-11-11 13:26:36 +03:00
|
|
|
def f_patched(self_):
|
|
|
|
calls[0] += 1
|
|
|
|
return f_orig(self_)
|
|
|
|
|
|
|
|
NamedTupleCursor._make_nt = f_patched
|
|
|
|
|
|
|
|
try:
|
|
|
|
curs = self.conn.cursor()
|
|
|
|
curs.execute("select * from nttest order by 1")
|
|
|
|
curs.fetchone()
|
|
|
|
curs.fetchone()
|
|
|
|
curs.fetchone()
|
|
|
|
self.assertEqual(1, calls[0])
|
|
|
|
|
|
|
|
curs.execute("select * from nttest order by 1")
|
|
|
|
curs.fetchone()
|
|
|
|
curs.fetchall()
|
|
|
|
self.assertEqual(2, calls[0])
|
|
|
|
|
|
|
|
curs.execute("select * from nttest order by 1")
|
|
|
|
curs.fetchone()
|
|
|
|
curs.fetchmany(1)
|
|
|
|
self.assertEqual(3, calls[0])
|
|
|
|
|
|
|
|
finally:
|
|
|
|
NamedTupleCursor._make_nt = f_orig
|
|
|
|
|
2011-04-26 22:18:39 +04:00
|
|
|
@skip_before_postgres(8, 0)
|
|
|
|
def test_named(self):
|
|
|
|
curs = self.conn.cursor('tmp')
|
|
|
|
curs.execute("""select i from generate_series(0,9) i""")
|
|
|
|
recs = []
|
|
|
|
recs.extend(curs.fetchmany(5))
|
|
|
|
recs.append(curs.fetchone())
|
|
|
|
recs.extend(curs.fetchall())
|
2017-12-04 05:47:19 +03:00
|
|
|
self.assertEqual(list(range(10)), [t.i for t in recs])
|
2011-04-26 22:18:39 +04:00
|
|
|
|
|
|
|
def test_named_fetchone(self):
|
|
|
|
curs = self.conn.cursor('tmp')
|
|
|
|
curs.execute("""select 42 as i""")
|
|
|
|
t = curs.fetchone()
|
|
|
|
self.assertEqual(t.i, 42)
|
|
|
|
|
|
|
|
def test_named_fetchmany(self):
|
|
|
|
curs = self.conn.cursor('tmp')
|
|
|
|
curs.execute("""select 42 as i""")
|
|
|
|
recs = curs.fetchmany(10)
|
|
|
|
self.assertEqual(recs[0].i, 42)
|
|
|
|
|
|
|
|
def test_named_fetchall(self):
|
|
|
|
curs = self.conn.cursor('tmp')
|
|
|
|
curs.execute("""select 42 as i""")
|
|
|
|
recs = curs.fetchall()
|
|
|
|
self.assertEqual(recs[0].i, 42)
|
|
|
|
|
2011-04-27 15:18:50 +04:00
|
|
|
@skip_before_postgres(8, 2)
|
2011-04-26 22:26:19 +04:00
|
|
|
def test_not_greedy(self):
|
|
|
|
curs = self.conn.cursor('tmp')
|
|
|
|
curs.itersize = 2
|
|
|
|
curs.execute("""select clock_timestamp() as ts from generate_series(1,3)""")
|
|
|
|
recs = []
|
|
|
|
for t in curs:
|
|
|
|
time.sleep(0.01)
|
|
|
|
recs.append(t)
|
|
|
|
|
|
|
|
# check that the dataset was not fetched in a single gulp
|
|
|
|
self.assert_(recs[1].ts - recs[0].ts < timedelta(seconds=0.005))
|
|
|
|
self.assert_(recs[2].ts - recs[1].ts > timedelta(seconds=0.0099))
|
|
|
|
|
2012-02-24 02:58:58 +04:00
|
|
|
@skip_before_postgres(8, 0)
|
|
|
|
def test_named_rownumber(self):
|
|
|
|
curs = self.conn.cursor('tmp')
|
|
|
|
# Only checking for dataset < itersize:
|
|
|
|
# see CursorTests.test_iter_named_cursor_rownumber
|
|
|
|
curs.itersize = 4
|
|
|
|
curs.execute("""select * from generate_series(1,3)""")
|
|
|
|
for i, t in enumerate(curs):
|
|
|
|
self.assertEqual(i + 1, curs.rownumber)
|
|
|
|
|
2010-11-06 04:39:43 +03:00
|
|
|
|
2007-11-11 13:40:12 +03:00
|
|
|
def test_suite():
|
|
|
|
return unittest.TestLoader().loadTestsFromName(__name__)
|
2005-01-13 19:50:29 +03:00
|
|
|
|
|
|
|
if __name__ == "__main__":
|
2007-11-11 13:40:12 +03:00
|
|
|
unittest.main()
|