@@ -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
@@ -946,31 +947,14 @@ Connection objects
946
947
947
948
.. attribute :: row_factory
948
949
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 `.
954
956
955
- .. doctest ::
956
-
957
- >>> def dict_factory (cursor , row ):
958
- ... col_names = [col[0 ] for col in cursor.description]
959
- ... return {key: value for key, value in zip (col_names, row)}
960
- >>> con = sqlite3.connect(" :memory:" )
961
- >>> con.row_factory = dict_factory
962
- >>> for row in 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.
974
958
975
959
.. attribute :: text_factory
976
960
@@ -1122,7 +1106,7 @@ Cursor objects
1122
1106
1123
1107
.. method :: fetchone()
1124
1108
1125
- If :attr: `~Connection .row_factory ` is ``None ``,
1109
+ If :attr: `~Cursor .row_factory ` is ``None ``,
1126
1110
return the next row query result set as a :class: `tuple `.
1127
1111
Else, pass it to the row factory and return its result.
1128
1112
Return ``None `` if no more data is available.
@@ -1216,6 +1200,22 @@ Cursor objects
1216
1200
including :abbr: `CTE ( Common Table Expression ) ` queries.
1217
1201
It is only updated by the :meth: `execute ` and :meth: `executemany ` methods.
1218
1202
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
+
1219
1219
1220
1220
.. The sqlite3.Row example used to be a how-to. It has now been incorporated
1221
1221
into the Row reference. We keep the anchor here in order not to break
@@ -1234,7 +1234,10 @@ Row objects
1234
1234
It supports iteration, equality testing, :func: `len `,
1235
1235
and :term: `mapping ` access by column name and index.
1236
1236
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.
1238
1241
1239
1242
.. method :: keys
1240
1243
@@ -1245,21 +1248,6 @@ Row objects
1245
1248
.. versionchanged :: 3.5
1246
1249
Added support of slicing.
1247
1250
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
-
1263
1251
1264
1252
PrepareProtocol objects
1265
1253
^^^^^^^^^^^^^^^^^^^^^^^
@@ -1855,6 +1843,96 @@ can be found in the `SQLite URI documentation`_.
1855
1843
.. _SQLite URI documentation : https://www.sqlite.org/uri.html
1856
1844
1857
1845
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 row in 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
+
1858
1936
.. _sqlite3-explanation :
1859
1937
1860
1938
Explanation
0 commit comments