@@ -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
@@ -1236,31 +1237,14 @@ Connection objects
12361237
12371238 ..attribute ::row_factory
12381239
1239- A callable that accepts two arguments,
1240- a:class: `Cursor ` object and the raw row results as a:class: `tuple `,
1241- and returns a custom object representing an SQLite row.
1242-
1243- Example:
1240+ The initial:attr: `~Cursor.row_factory `
1241+ for:class: `Cursor ` objects created from this connection.
1242+ Assigning to this attribute does not affect the:attr: `!row_factory `
1243+ of existing cursors belonging to this connection, only new ones.
1244+ Is ``None `` by default,
1245+ meaning each row is returned as a:class: `tuple `.
12441246
1245- ..doctest ::
1246-
1247- >>>def dict_factory (cursor ,row ):
1248- ...col_names= [col[0 ]for colin cursor.description]
1249- ...return {key: valuefor key, valuein zip (col_names, row)}
1250- >>>con= sqlite3.connect(" :memory:" )
1251- >>>con.row_factory= dict_factory
1252- >>>for rowin con.execute(" SELECT 1 AS a, 2 AS b" ):
1253- ...print (row)
1254- {'a': 1, 'b': 2}
1255-
1256- If returning a tuple doesn't suffice and you want name-based access to
1257- columns, you should consider setting:attr: `row_factory ` to the
1258- highly optimized:class: `sqlite3.Row ` type.:class: `Row ` provides both
1259- index-based and case-insensitive name-based access to columns with almost no
1260- memory overhead. It will probably be better than your own custom
1261- dictionary-based approach or even a db_row based solution.
1262-
1263- .. XXX what's a db_row-based solution?
1247+ See:ref: `sqlite3-howto-row-factory ` for more details.
12641248
12651249 ..attribute ::text_factory
12661250
@@ -1413,7 +1397,7 @@ Cursor objects
14131397
14141398 ..method ::fetchone()
14151399
1416- If:attr: `~Connection .row_factory ` is ``None ``,
1400+ If:attr: `~Cursor .row_factory ` is ``None ``,
14171401 return the next row query result set as a:class: `tuple `.
14181402 Else, pass it to the row factory and return its result.
14191403 Return ``None `` if no more data is available.
@@ -1507,6 +1491,22 @@ Cursor objects
15071491 including:abbr: `CTE ( Common Table Expression ) ` queries.
15081492 It is only updated by the:meth: `execute ` and:meth: `executemany ` methods.
15091493
1494+ ..attribute ::row_factory
1495+
1496+ Control how a row fetched from this:class: `!Cursor ` is represented.
1497+ If ``None ``, a row is represented as a:class: `tuple `.
1498+ Can be set to the included:class: `sqlite3.Row `;
1499+ or a:term: `callable ` that accepts two arguments,
1500+ a:class: `Cursor ` object and the:class: `!tuple ` of row values,
1501+ and returns a custom object representing an SQLite row.
1502+
1503+ Defaults to what:attr: `Connection.row_factory ` was set to
1504+ when the:class: `!Cursor ` was created.
1505+ Assigning to this attribute does not affect
1506+ :attr: `Connection.row_factory ` of the parent connection.
1507+
1508+ See:ref: `sqlite3-howto-row-factory ` for more details.
1509+
15101510
15111511.. The sqlite3.Row example used to be a how-to. It has now been incorporated
15121512 into the Row reference. We keep the anchor here in order not to break
@@ -1525,7 +1525,10 @@ Row objects
15251525 It supports iteration, equality testing,:func: `len `,
15261526 and:term: `mapping ` access by column name and index.
15271527
1528- Two row objects compare equal if have equal columns and equal members.
1528+ Two:class: `!Row ` objects compare equal
1529+ if they have identical column names and values.
1530+
1531+ See:ref: `sqlite3-howto-row-factory ` for more details.
15291532
15301533 ..method ::keys
15311534
@@ -1536,21 +1539,6 @@ Row objects
15361539 ..versionchanged ::3.5
15371540 Added support of slicing.
15381541
1539- Example:
1540-
1541- ..doctest ::
1542-
1543- >>>con= sqlite3.connect(" :memory:" )
1544- >>>con.row_factory= sqlite3.Row
1545- >>>res= con.execute(" SELECT 'Earth' AS name, 6378 AS radius" )
1546- >>>row= res.fetchone()
1547- >>>row.keys()
1548- ['name', 'radius']
1549- >>>row[0 ], row[" name" ]# Access by index and name.
1550- ('Earth', 'Earth')
1551- >>>row[" RADIUS" ]# Column names are case-insensitive.
1552- 6378
1553-
15541542
15551543.. _sqlite3-blob-objects :
15561544
@@ -2241,6 +2229,96 @@ can be found in the `SQLite URI documentation`_.
22412229.. _SQLite URI documentation :https://www.sqlite.org/uri.html
22422230
22432231
2232+ .. _sqlite3-howto-row-factory :
2233+
2234+ How to create and use row factories
2235+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2236+
2237+ By default,:mod: `!sqlite3 ` represents each row as a:class: `tuple `.
2238+ If a:class: `!tuple ` does not suit your needs,
2239+ you can use the:class: `sqlite3.Row ` class
2240+ or a custom:attr: `~Cursor.row_factory `.
2241+
2242+ While:attr: `!row_factory ` exists as an attribute both on the
2243+ :class: `Cursor ` and the:class: `Connection `,
2244+ it is recommended to set:class: `Connection.row_factory `,
2245+ so all cursors created from the connection will use the same row factory.
2246+
2247+ :class: `!Row ` provides indexed and case-insensitive named access to columns,
2248+ with minimal memory overhead and performance impact over a:class: `!tuple `.
2249+ To use:class: `!Row ` as a row factory,
2250+ assign it to the:attr: `!row_factory ` attribute:
2251+
2252+ ..doctest ::
2253+
2254+ >>>con= sqlite3.connect(" :memory:" )
2255+ >>>con.row_factory= sqlite3.Row
2256+
2257+ Queries now return:class: `!Row ` objects:
2258+
2259+ ..doctest ::
2260+
2261+ >>>res= con.execute(" SELECT 'Earth' AS name, 6378 AS radius" )
2262+ >>>row= res.fetchone()
2263+ >>>row.keys()
2264+ ['name', 'radius']
2265+ >>>row[0 ]# Access by index.
2266+ 'Earth'
2267+ >>>row[" name" ]# Access by name.
2268+ 'Earth'
2269+ >>>row[" RADIUS" ]# Column names are case-insensitive.
2270+ 6378
2271+
2272+ You can create a custom:attr: `~Cursor.row_factory `
2273+ that returns each row as a:class: `dict `, with column names mapped to values:
2274+
2275+ ..testcode ::
2276+
2277+ def dict_factory(cursor, row):
2278+ fields = [column[0] for column in cursor.description]
2279+ return {key: value for key, value in zip(fields, row)}
2280+
2281+ Using it, queries now return a:class: `!dict ` instead of a:class: `!tuple `:
2282+
2283+ ..doctest ::
2284+
2285+ >>>con= sqlite3.connect(" :memory:" )
2286+ >>>con.row_factory= dict_factory
2287+ >>>for rowin con.execute(" SELECT 1 AS a, 2 AS b" ):
2288+ ...print (row)
2289+ {'a': 1, 'b': 2}
2290+
2291+ The following row factory returns a:term: `named tuple `:
2292+
2293+ ..testcode ::
2294+
2295+ from collections import namedtuple
2296+
2297+ def namedtuple_factory(cursor, row):
2298+ fields = [column[0] for column in cursor.description]
2299+ cls = namedtuple("Row", fields)
2300+ return cls._make(row)
2301+
2302+ :func: `!namedtuple_factory ` can be used as follows:
2303+
2304+ ..doctest ::
2305+
2306+ >>>con= sqlite3.connect(" :memory:" )
2307+ >>>con.row_factory= namedtuple_factory
2308+ >>>cur= con.execute(" SELECT 1 AS a, 2 AS b" )
2309+ >>>row= cur.fetchone()
2310+ >>>row
2311+ Row(a=1, b=2)
2312+ >>>row[0 ]# Indexed access.
2313+ 1
2314+ >>>row.b# Attribute access.
2315+ 2
2316+
2317+ With some adjustments, the above recipe can be adapted to use a
2318+ :class: `~dataclasses.dataclass `, or any other custom class,
2319+ instead of a:class: `~collections.namedtuple `.
2320+
2321+
22442322.. _sqlite3-explanation :
22452323
22462324Explanation