diff -r 811d91591f73 Doc/library/sqlite3.rst --- a/Doc/library/sqlite3.rst Mon Aug 20 10:19:12 2012 +1000 +++ b/Doc/library/sqlite3.rst Mon Aug 20 13:18:00 2012 +1000 @@ -645,6 +645,55 @@ 35.14 +NamedTupleRow Objects +--------------------- + +.. function:: NamedTupleRow + + A :func:`NamedTupleRow` instance serves as a + :attr:`~Connection.row_factory` for :class:`Connection` objects. + It returns a :func:`~collections.namedtuple` representation of a + row. + +Let's assume we initialize a table as in the example given above:: + + conn = sqlite3.connect(":memory:") + c = conn.cursor() + c.execute('''create table stocks + (date text, trans text, symbol text, + qty real, price real)''') + c.execute("""insert into stocks + values ('2006-01-05','BUY','RHAT',100,35.14)""") + conn.commit() + c.close() + +Now we plug :func:`NamedTupleRow` in:: + + >>> conn.row_factory = sqlite3.NamedTupleRow + >>> c = conn.cursor() + >>> c.execute('select * from stocks') + + >>> r = c.fetchone() + >>> type(r) + + >>> r + Row(date='2006-01-05', trans='BUY', symbol='RHAT', qty=100.0, price=35.14) + >>> len(r) + 5 + >>> r[2] + 'RHAT' + >>> r.qty + 100.0 + >>> for member in r: + ... print(member) + ... + 2006-01-05 + BUY + RHAT + 100.0 + 35.14 + + .. _sqlite3-types: SQLite and Python types diff -r 811d91591f73 Lib/sqlite3/__init__.py --- a/Lib/sqlite3/__init__.py Mon Aug 20 10:19:12 2012 +1000 +++ b/Lib/sqlite3/__init__.py Mon Aug 20 13:18:00 2012 +1000 @@ -21,3 +21,4 @@ # 3. This notice may not be removed or altered from any source distribution. from sqlite3.dbapi2 import * +from sqlite3.namedtuple import NamedTupleRow diff -r 811d91591f73 Lib/sqlite3/namedtuple.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Lib/sqlite3/namedtuple.py Mon Aug 20 13:18:00 2012 +1000 @@ -0,0 +1,18 @@ +from functools import lru_cache +from collections import namedtuple + + +def NamedTupleRow(cursor, row): + """ + Return a namedtuple row factory for connection objects. + """ + return _namedtuple_row(cursor)(*row) + + +@lru_cache(maxsize=20) +def _namedtuple_row(cursor): + """ + Return a namedtuple representation of the column names. + """ + fields = [col[0] for col in cursor.description] + return namedtuple("Row", fields) diff -r 811d91591f73 Lib/sqlite3/test/factory.py --- a/Lib/sqlite3/test/factory.py Mon Aug 20 10:19:12 2012 +1000 +++ b/Lib/sqlite3/test/factory.py Mon Aug 20 13:18:00 2012 +1000 @@ -151,6 +151,20 @@ self.assertNotEqual(row_1, row_3) self.assertNotEqual(hash(row_1), hash(row_3)) + def CheckSqliteNamedTuple(self): + self.con.row_factory = sqlite.NamedTupleRow + row = self.con.execute("select 1 as a, 2 as b").fetchone() + self.assertTrue(issubclass(row.__class__, tuple), + "row is not instance of Tuple.") + + col1, col2 = row.a, row.b + self.assertTrue(col1 == 1, "by name: wrong result for column 'a'") + self.assertTrue(col2 == 2, "by name: wrong result for column 'a'") + + col1, col2 = row[0], row[1] + self.assertTrue(col1 == 1, "by index: wrong result for column 0") + self.assertTrue(col2 == 2, "by index: wrong result for column 1") + def tearDown(self): self.con.close()