@@ -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
@@ -1316,31 +1317,14 @@ Connection objects
1316
1317
1317
1318
.. attribute :: row_factory
1318
1319
1319
- A callable that accepts two arguments,
1320
- a :class: `Cursor ` object and the raw row results as a :class: `tuple `,
1321
- and returns a custom object representing an SQLite row.
1322
-
1323
- Example:
1320
+ The initial :attr: `~Cursor.row_factory `
1321
+ for :class: `Cursor ` objects created from this connection.
1322
+ Assigning to this attribute does not affect the :attr: `!row_factory `
1323
+ of existing cursors belonging to this connection, only new ones.
1324
+ Is ``None `` by default,
1325
+ meaning each row is returned as a :class: `tuple `.
1324
1326
1325
- .. doctest ::
1326
-
1327
- >>> def dict_factory (cursor , row ):
1328
- ... col_names = [col[0 ] for col in cursor.description]
1329
- ... return {key: value for key, value in zip (col_names, row)}
1330
- >>> con = sqlite3.connect(" :memory:" )
1331
- >>> con.row_factory = dict_factory
1332
- >>> for row in con.execute(" SELECT 1 AS a, 2 AS b" ):
1333
- ... print (row)
1334
- {'a': 1, 'b': 2}
1335
-
1336
- If returning a tuple doesn't suffice and you want name-based access to
1337
- columns, you should consider setting :attr: `row_factory ` to the
1338
- highly optimized :class: `sqlite3.Row ` type. :class: `Row ` provides both
1339
- index-based and case-insensitive name-based access to columns with almost no
1340
- memory overhead. It will probably be better than your own custom
1341
- dictionary-based approach or even a db_row based solution.
1342
-
1343
- .. XXX what's a db_row-based solution?
1327
+ See :ref: `sqlite3-howto-row-factory ` for more details.
1344
1328
1345
1329
.. attribute :: text_factory
1346
1330
@@ -1497,7 +1481,7 @@ Cursor objects
1497
1481
1498
1482
.. method :: fetchone()
1499
1483
1500
- If :attr: `~Connection .row_factory ` is ``None ``,
1484
+ If :attr: `~Cursor .row_factory ` is ``None ``,
1501
1485
return the next row query result set as a :class: `tuple `.
1502
1486
Else, pass it to the row factory and return its result.
1503
1487
Return ``None `` if no more data is available.
@@ -1591,6 +1575,22 @@ Cursor objects
1591
1575
including :abbr: `CTE ( Common Table Expression ) ` queries.
1592
1576
It is only updated by the :meth: `execute ` and :meth: `executemany ` methods.
1593
1577
1578
+ .. attribute :: row_factory
1579
+
1580
+ Control how a row fetched from this :class: `!Cursor ` is represented.
1581
+ If ``None ``, a row is represented as a :class: `tuple `.
1582
+ Can be set to the included :class: `sqlite3.Row `;
1583
+ or a :term: `callable ` that accepts two arguments,
1584
+ a :class: `Cursor ` object and the :class: `!tuple ` of row values,
1585
+ and returns a custom object representing an SQLite row.
1586
+
1587
+ Defaults to what :attr: `Connection.row_factory ` was set to
1588
+ when the :class: `!Cursor ` was created.
1589
+ Assigning to this attribute does not affect
1590
+ :attr: `Connection.row_factory ` of the parent connection.
1591
+
1592
+ See :ref: `sqlite3-howto-row-factory ` for more details.
1593
+
1594
1594
1595
1595
.. The sqlite3.Row example used to be a how-to. It has now been incorporated
1596
1596
into the Row reference. We keep the anchor here in order not to break
@@ -1609,7 +1609,10 @@ Row objects
1609
1609
It supports iteration, equality testing, :func: `len `,
1610
1610
and :term: `mapping ` access by column name and index.
1611
1611
1612
- Two row objects compare equal if have equal columns and equal members.
1612
+ Two :class: `!Row ` objects compare equal
1613
+ if they have identical column names and values.
1614
+
1615
+ See :ref: `sqlite3-howto-row-factory ` for more details.
1613
1616
1614
1617
.. method :: keys
1615
1618
@@ -1620,21 +1623,6 @@ Row objects
1620
1623
.. versionchanged :: 3.5
1621
1624
Added support of slicing.
1622
1625
1623
- Example:
1624
-
1625
- .. doctest ::
1626
-
1627
- >>> con = sqlite3.connect(" :memory:" )
1628
- >>> con.row_factory = sqlite3.Row
1629
- >>> res = con.execute(" SELECT 'Earth' AS name, 6378 AS radius" )
1630
- >>> row = res.fetchone()
1631
- >>> row.keys()
1632
- ['name', 'radius']
1633
- >>> row[0 ], row[" name" ] # Access by index and name.
1634
- ('Earth', 'Earth')
1635
- >>> row[" RADIUS" ] # Column names are case-insensitive.
1636
- 6378
1637
-
1638
1626
1639
1627
.. _sqlite3-blob-objects :
1640
1628
@@ -2358,6 +2346,96 @@ can be found in the `SQLite URI documentation`_.
2358
2346
.. _SQLite URI documentation : https://www.sqlite.org/uri.html
2359
2347
2360
2348
2349
+ .. _sqlite3-howto-row-factory :
2350
+
2351
+ How to create and use row factories
2352
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2353
+
2354
+ By default, :mod: `!sqlite3 ` represents each row as a :class: `tuple `.
2355
+ If a :class: `!tuple ` does not suit your needs,
2356
+ you can use the :class: `sqlite3.Row ` class
2357
+ or a custom :attr: `~Cursor.row_factory `.
2358
+
2359
+ While :attr: `!row_factory ` exists as an attribute both on the
2360
+ :class: `Cursor ` and the :class: `Connection `,
2361
+ it is recommended to set :class: `Connection.row_factory `,
2362
+ so all cursors created from the connection will use the same row factory.
2363
+
2364
+ :class: `!Row ` provides indexed and case-insensitive named access to columns,
2365
+ with minimal memory overhead and performance impact over a :class: `!tuple `.
2366
+ To use :class: `!Row ` as a row factory,
2367
+ assign it to the :attr: `!row_factory ` attribute:
2368
+
2369
+ .. doctest ::
2370
+
2371
+ >>> con = sqlite3.connect(" :memory:" )
2372
+ >>> con.row_factory = sqlite3.Row
2373
+
2374
+ Queries now return :class: `!Row ` objects:
2375
+
2376
+ .. doctest ::
2377
+
2378
+ >>> res = con.execute(" SELECT 'Earth' AS name, 6378 AS radius" )
2379
+ >>> row = res.fetchone()
2380
+ >>> row.keys()
2381
+ ['name', 'radius']
2382
+ >>> row[0 ] # Access by index.
2383
+ 'Earth'
2384
+ >>> row[" name" ] # Access by name.
2385
+ 'Earth'
2386
+ >>> row[" RADIUS" ] # Column names are case-insensitive.
2387
+ 6378
2388
+
2389
+ You can create a custom :attr: `~Cursor.row_factory `
2390
+ that returns each row as a :class: `dict `, with column names mapped to values:
2391
+
2392
+ .. testcode ::
2393
+
2394
+ def dict_factory(cursor, row):
2395
+ fields = [column[0] for column in cursor.description]
2396
+ return {key: value for key, value in zip(fields, row)}
2397
+
2398
+ Using it, queries now return a :class: `!dict ` instead of a :class: `!tuple `:
2399
+
2400
+ .. doctest ::
2401
+
2402
+ >>> con = sqlite3.connect(" :memory:" )
2403
+ >>> con.row_factory = dict_factory
2404
+ >>> for row in con.execute(" SELECT 1 AS a, 2 AS b" ):
2405
+ ... print (row)
2406
+ {'a': 1, 'b': 2}
2407
+
2408
+ The following row factory returns a :term: `named tuple `:
2409
+
2410
+ .. testcode ::
2411
+
2412
+ from collections import namedtuple
2413
+
2414
+ def namedtuple_factory(cursor, row):
2415
+ fields = [column[0] for column in cursor.description]
2416
+ cls = namedtuple("Row", fields)
2417
+ return cls._make(row)
2418
+
2419
+ :func: `!namedtuple_factory ` can be used as follows:
2420
+
2421
+ .. doctest ::
2422
+
2423
+ >>> con = sqlite3.connect(" :memory:" )
2424
+ >>> con.row_factory = namedtuple_factory
2425
+ >>> cur = con.execute(" SELECT 1 AS a, 2 AS b" )
2426
+ >>> row = cur.fetchone()
2427
+ >>> row
2428
+ Row(a=1, b=2)
2429
+ >>> row[0 ] # Indexed access.
2430
+ 1
2431
+ >>> row.b # Attribute access.
2432
+ 2
2433
+
2434
+ With some adjustments, the above recipe can be adapted to use a
2435
+ :class: `~dataclasses.dataclass `, or any other custom class,
2436
+ instead of a :class: `~collections.namedtuple `.
2437
+
2438
+
2361
2439
.. _sqlite3-explanation :
2362
2440
2363
2441
Explanation
0 commit comments