@@ -239,6 +239,7 @@ inserted data and retrieved values from it in multiple ways.
239239 *:ref: `sqlite3-adapters `
240240 *:ref: `sqlite3-converters `
241241 *:ref: `sqlite3-connection-context-manager `
242+ *:ref: `sqlite3-howto-row-factory `
242243
243244 *:ref: `sqlite3-explanation ` for in-depth background on transaction control.
244245
@@ -946,31 +947,14 @@ Connection objects
946947
947948 ..attribute ::row_factory
948949
949- A callable that accepts two arguments,
950- a:class: `Cursor ` object and the raw row results as a:class: `tuple `,
951- and returns a custom object representing an SQLite row.
952-
953- Example:
950+ The initial:attr: `~Cursor.row_factory `
951+ for:class: `Cursor ` objects created from this connection.
952+ Assigning to this attribute does not affect the:attr: `!row_factory `
953+ of existing cursors belonging to this connection, only new ones.
954+ Is ``None `` by default,
955+ meaning each row is returned as a:class: `tuple `.
954956
955- ..doctest ::
956-
957- >>>def dict_factory (cursor ,row ):
958- ...col_names= [col[0 ]for colin cursor.description]
959- ...return {key: valuefor key, valuein zip (col_names, row)}
960- >>>con= sqlite3.connect(" :memory:" )
961- >>>con.row_factory= dict_factory
962- >>>for rowin con.execute(" SELECT 1 AS a, 2 AS b" ):
963- ...print (row)
964- {'a': 1, 'b': 2}
965-
966- If returning a tuple doesn't suffice and you want name-based access to
967- columns, you should consider setting:attr: `row_factory ` to the
968- highly optimized:class: `sqlite3.Row ` type.:class: `Row ` provides both
969- index-based and case-insensitive name-based access to columns with almost no
970- memory overhead. It will probably be better than your own custom
971- dictionary-based approach or even a db_row based solution.
972-
973- .. XXX what's a db_row-based solution?
957+ See:ref: `sqlite3-howto-row-factory ` for more details.
974958
975959 ..attribute ::text_factory
976960
@@ -1122,7 +1106,7 @@ Cursor objects
11221106
11231107 ..method ::fetchone()
11241108
1125- If:attr: `~Connection .row_factory ` is ``None ``,
1109+ If:attr: `~Cursor .row_factory ` is ``None ``,
11261110 return the next row query result set as a:class: `tuple `.
11271111 Else, pass it to the row factory and return its result.
11281112 Return ``None `` if no more data is available.
@@ -1216,6 +1200,22 @@ Cursor objects
12161200 including:abbr: `CTE ( Common Table Expression ) ` queries.
12171201 It is only updated by the:meth: `execute ` and:meth: `executemany ` methods.
12181202
1203+ ..attribute ::row_factory
1204+
1205+ Control how a row fetched from this:class: `!Cursor ` is represented.
1206+ If ``None ``, a row is represented as a:class: `tuple `.
1207+ Can be set to the included:class: `sqlite3.Row `;
1208+ or a:term: `callable ` that accepts two arguments,
1209+ a:class: `Cursor ` object and the:class: `!tuple ` of row values,
1210+ and returns a custom object representing an SQLite row.
1211+
1212+ Defaults to what:attr: `Connection.row_factory ` was set to
1213+ when the:class: `!Cursor ` was created.
1214+ Assigning to this attribute does not affect
1215+ :attr: `Connection.row_factory ` of the parent connection.
1216+
1217+ See:ref: `sqlite3-howto-row-factory ` for more details.
1218+
12191219
12201220.. The sqlite3.Row example used to be a how-to. It has now been incorporated
12211221 into the Row reference. We keep the anchor here in order not to break
@@ -1234,7 +1234,10 @@ Row objects
12341234 It supports iteration, equality testing,:func: `len `,
12351235 and:term: `mapping ` access by column name and index.
12361236
1237- Two row objects compare equal if have equal columns and equal members.
1237+ Two:class: `!Row ` objects compare equal
1238+ if they have identical column names and values.
1239+
1240+ See:ref: `sqlite3-howto-row-factory ` for more details.
12381241
12391242 ..method ::keys
12401243
@@ -1245,21 +1248,6 @@ Row objects
12451248 ..versionchanged ::3.5
12461249 Added support of slicing.
12471250
1248- Example:
1249-
1250- ..doctest ::
1251-
1252- >>>con= sqlite3.connect(" :memory:" )
1253- >>>con.row_factory= sqlite3.Row
1254- >>>res= con.execute(" SELECT 'Earth' AS name, 6378 AS radius" )
1255- >>>row= res.fetchone()
1256- >>>row.keys()
1257- ['name', 'radius']
1258- >>>row[0 ], row[" name" ]# Access by index and name.
1259- ('Earth', 'Earth')
1260- >>>row[" RADIUS" ]# Column names are case-insensitive.
1261- 6378
1262-
12631251
12641252PrepareProtocol objects
12651253^^^^^^^^^^^^^^^^^^^^^^^
@@ -1855,6 +1843,96 @@ can be found in the `SQLite URI documentation`_.
18551843.. _SQLite URI documentation :https://www.sqlite.org/uri.html
18561844
18571845
1846+ .. _sqlite3-howto-row-factory :
1847+
1848+ How to create and use row factories
1849+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1850+
1851+ By default,:mod: `!sqlite3 ` represents each row as a:class: `tuple `.
1852+ If a:class: `!tuple ` does not suit your needs,
1853+ you can use the:class: `sqlite3.Row ` class
1854+ or a custom:attr: `~Cursor.row_factory `.
1855+
1856+ While:attr: `!row_factory ` exists as an attribute both on the
1857+ :class: `Cursor ` and the:class: `Connection `,
1858+ it is recommended to set:class: `Connection.row_factory `,
1859+ so all cursors created from the connection will use the same row factory.
1860+
1861+ :class: `!Row ` provides indexed and case-insensitive named access to columns,
1862+ with minimal memory overhead and performance impact over a:class: `!tuple `.
1863+ To use:class: `!Row ` as a row factory,
1864+ assign it to the:attr: `!row_factory ` attribute:
1865+
1866+ ..doctest ::
1867+
1868+ >>>con= sqlite3.connect(" :memory:" )
1869+ >>>con.row_factory= sqlite3.Row
1870+
1871+ Queries now return:class: `!Row ` objects:
1872+
1873+ ..doctest ::
1874+
1875+ >>>res= con.execute(" SELECT 'Earth' AS name, 6378 AS radius" )
1876+ >>>row= res.fetchone()
1877+ >>>row.keys()
1878+ ['name', 'radius']
1879+ >>>row[0 ]# Access by index.
1880+ 'Earth'
1881+ >>>row[" name" ]# Access by name.
1882+ 'Earth'
1883+ >>>row[" RADIUS" ]# Column names are case-insensitive.
1884+ 6378
1885+
1886+ You can create a custom:attr: `~Cursor.row_factory `
1887+ that returns each row as a:class: `dict `, with column names mapped to values:
1888+
1889+ ..testcode ::
1890+
1891+ def dict_factory(cursor, row):
1892+ fields = [column[0] for column in cursor.description]
1893+ return {key: value for key, value in zip(fields, row)}
1894+
1895+ Using it, queries now return a:class: `!dict ` instead of a:class: `!tuple `:
1896+
1897+ ..doctest ::
1898+
1899+ >>>con= sqlite3.connect(" :memory:" )
1900+ >>>con.row_factory= dict_factory
1901+ >>>for rowin con.execute(" SELECT 1 AS a, 2 AS b" ):
1902+ ...print (row)
1903+ {'a': 1, 'b': 2}
1904+
1905+ The following row factory returns a:term: `named tuple `:
1906+
1907+ ..testcode ::
1908+
1909+ from collections import namedtuple
1910+
1911+ def namedtuple_factory(cursor, row):
1912+ fields = [column[0] for column in cursor.description]
1913+ cls = namedtuple("Row", fields)
1914+ return cls._make(row)
1915+
1916+ :func: `!namedtuple_factory ` can be used as follows:
1917+
1918+ ..doctest ::
1919+
1920+ >>>con= sqlite3.connect(" :memory:" )
1921+ >>>con.row_factory= namedtuple_factory
1922+ >>>cur= con.execute(" SELECT 1 AS a, 2 AS b" )
1923+ >>>row= cur.fetchone()
1924+ >>>row
1925+ Row(a=1, b=2)
1926+ >>>row[0 ]# Indexed access.
1927+ 1
1928+ >>>row.b# Attribute access.
1929+ 2
1930+
1931+ With some adjustments, the above recipe can be adapted to use a
1932+ :class: `~dataclasses.dataclass `, or any other custom class,
1933+ instead of a:class: `~collections.namedtuple `.
1934+
1935+
18581936.. _sqlite3-explanation :
18591937
18601938Explanation