@@ -239,6 +239,7 @@ inserted data and retrieved values from it in multiple ways.
239
239
* :ref: `sqlite3-adapters `
240
240
* :ref: `sqlite3-converters `
241
241
* :ref: `sqlite3-connection-context-manager `
242
+ * :ref: `sqlite3-howto-row-factory `
242
243
243
244
* :ref: `sqlite3-explanation ` for in-depth background on transaction control.
244
245
@@ -1236,31 +1237,14 @@ Connection objects
1236
1237
1237
1238
.. attribute :: row_factory
1238
1239
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 `.
1244
1246
1245
- .. doctest ::
1246
-
1247
- >>> def dict_factory (cursor , row ):
1248
- ... col_names = [col[0 ] for col in cursor.description]
1249
- ... return {key: value for key, value in zip (col_names, row)}
1250
- >>> con = sqlite3.connect(" :memory:" )
1251
- >>> con.row_factory = dict_factory
1252
- >>> for row in 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.
1264
1248
1265
1249
.. attribute :: text_factory
1266
1250
@@ -1413,7 +1397,7 @@ Cursor objects
1413
1397
1414
1398
.. method :: fetchone()
1415
1399
1416
- If :attr: `~Connection .row_factory ` is ``None ``,
1400
+ If :attr: `~Cursor .row_factory ` is ``None ``,
1417
1401
return the next row query result set as a :class: `tuple `.
1418
1402
Else, pass it to the row factory and return its result.
1419
1403
Return ``None `` if no more data is available.
@@ -1507,6 +1491,22 @@ Cursor objects
1507
1491
including :abbr: `CTE ( Common Table Expression ) ` queries.
1508
1492
It is only updated by the :meth: `execute ` and :meth: `executemany ` methods.
1509
1493
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
+
1510
1510
1511
1511
.. The sqlite3.Row example used to be a how-to. It has now been incorporated
1512
1512
into the Row reference. We keep the anchor here in order not to break
@@ -1525,7 +1525,10 @@ Row objects
1525
1525
It supports iteration, equality testing, :func: `len `,
1526
1526
and :term: `mapping ` access by column name and index.
1527
1527
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.
1529
1532
1530
1533
.. method :: keys
1531
1534
@@ -1536,21 +1539,6 @@ Row objects
1536
1539
.. versionchanged :: 3.5
1537
1540
Added support of slicing.
1538
1541
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
-
1554
1542
1555
1543
.. _sqlite3-blob-objects :
1556
1544
@@ -2241,6 +2229,96 @@ can be found in the `SQLite URI documentation`_.
2241
2229
.. _SQLite URI documentation : https://www.sqlite.org/uri.html
2242
2230
2243
2231
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 row in 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
+
2244
2322
.. _sqlite3-explanation :
2245
2323
2246
2324
Explanation
0 commit comments