From 7e469c1f85dbeec29bd0be5ca8fe0e06c257fd22 Mon Sep 17 00:00:00 2001 From: xtreak Date: Thu, 6 Sep 2018 07:35:46 +0000 Subject: [PATCH 1/9] Clarify calling close when connection is used in a context manager --- Doc/library/sqlite3.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 9e3c56b5f9189e4..7368ad2cc2ff080 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -1074,7 +1074,8 @@ Using the connection as a context manager ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Connection objects can be used as context managers -that automatically commit or rollback transactions. In the event of an +that automatically commit or rollback transactions. Note that this does not +automatically call :meth:`close` on the connection object. In the event of an exception, the transaction is rolled back; otherwise, the transaction is committed: From 0aa804424842861cd417475e15a4b24b6d0fc673 Mon Sep 17 00:00:00 2001 From: xtreak Date: Sat, 8 Sep 2018 23:01:16 +0530 Subject: [PATCH 2/9] Call con.close in the end to close the connection --- Doc/includes/sqlite3/ctx_manager.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Doc/includes/sqlite3/ctx_manager.py b/Doc/includes/sqlite3/ctx_manager.py index 7af4ad1ecfbccaf..7e9e322edf0649e 100644 --- a/Doc/includes/sqlite3/ctx_manager.py +++ b/Doc/includes/sqlite3/ctx_manager.py @@ -14,3 +14,5 @@ con.execute("insert into person(firstname) values (?)", ("Joe",)) except sqlite3.IntegrityError: print("couldn't add Joe twice") + +con.close() From 84bca261be26a957a305048a5d8e600683791556 Mon Sep 17 00:00:00 2001 From: xtreak Date: Sat, 8 Sep 2018 23:17:21 +0530 Subject: [PATCH 3/9] Revert the additional statement in the doc. This reverts commit 7e469c1f85dbeec29bd0be5ca8fe0e06c257fd22. --- Doc/library/sqlite3.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 7368ad2cc2ff080..9e3c56b5f9189e4 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -1074,8 +1074,7 @@ Using the connection as a context manager ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Connection objects can be used as context managers -that automatically commit or rollback transactions. Note that this does not -automatically call :meth:`close` on the connection object. In the event of an +that automatically commit or rollback transactions. In the event of an exception, the transaction is rolled back; otherwise, the transaction is committed: From 40a98b2f56e40d0f98c3e31d8ab4343832634ad4 Mon Sep 17 00:00:00 2001 From: xtreak Date: Sat, 8 Sep 2018 23:58:02 +0530 Subject: [PATCH 4/9] Add con.close() to all example files --- Doc/includes/sqlite3/adapter_datetime.py | 2 ++ Doc/includes/sqlite3/adapter_point_1.py | 2 ++ Doc/includes/sqlite3/adapter_point_2.py | 2 ++ Doc/includes/sqlite3/connect_db_1.py | 1 + Doc/includes/sqlite3/connect_db_2.py | 1 + Doc/includes/sqlite3/countcursors.py | 2 ++ Doc/includes/sqlite3/execsql_fetchonerow.py | 2 ++ Doc/includes/sqlite3/execsql_printall_1.py | 2 ++ Doc/includes/sqlite3/execute_1.py | 2 ++ Doc/includes/sqlite3/execute_3.py | 2 ++ Doc/includes/sqlite3/executemany_1.py | 2 ++ Doc/includes/sqlite3/executemany_2.py | 2 ++ Doc/includes/sqlite3/insert_more_people.py | 2 ++ Doc/includes/sqlite3/load_extension.py | 2 ++ Doc/includes/sqlite3/md5func.py | 2 ++ Doc/includes/sqlite3/mysumaggr.py | 2 ++ Doc/includes/sqlite3/parse_colnames.py | 2 ++ Doc/includes/sqlite3/pysqlite_datetime.py | 2 ++ Doc/includes/sqlite3/row_factory.py | 2 ++ Doc/includes/sqlite3/rowclass.py | 2 ++ Doc/includes/sqlite3/shortcut_methods.py | 2 ++ Doc/includes/sqlite3/simple_tableprinter.py | 2 ++ Doc/includes/sqlite3/text_factory.py | 2 ++ 23 files changed, 44 insertions(+) diff --git a/Doc/includes/sqlite3/adapter_datetime.py b/Doc/includes/sqlite3/adapter_datetime.py index be33395100c325e..d5221d80c35c8ac 100644 --- a/Doc/includes/sqlite3/adapter_datetime.py +++ b/Doc/includes/sqlite3/adapter_datetime.py @@ -13,3 +13,5 @@ def adapt_datetime(ts): now = datetime.datetime.now() cur.execute("select ?", (now,)) print(cur.fetchone()[0]) + +con.close() diff --git a/Doc/includes/sqlite3/adapter_point_1.py b/Doc/includes/sqlite3/adapter_point_1.py index 6b1af8415648a47..77daf8f16d227b8 100644 --- a/Doc/includes/sqlite3/adapter_point_1.py +++ b/Doc/includes/sqlite3/adapter_point_1.py @@ -14,3 +14,5 @@ def __conform__(self, protocol): p = Point(4.0, -3.2) cur.execute("select ?", (p,)) print(cur.fetchone()[0]) + +con.close() diff --git a/Doc/includes/sqlite3/adapter_point_2.py b/Doc/includes/sqlite3/adapter_point_2.py index d670700f0491b17..cb86331692b61d5 100644 --- a/Doc/includes/sqlite3/adapter_point_2.py +++ b/Doc/includes/sqlite3/adapter_point_2.py @@ -15,3 +15,5 @@ def adapt_point(point): p = Point(4.0, -3.2) cur.execute("select ?", (p,)) print(cur.fetchone()[0]) + +con.close() diff --git a/Doc/includes/sqlite3/connect_db_1.py b/Doc/includes/sqlite3/connect_db_1.py index 1b975232865aef2..448e69c11c790bf 100644 --- a/Doc/includes/sqlite3/connect_db_1.py +++ b/Doc/includes/sqlite3/connect_db_1.py @@ -1,3 +1,4 @@ import sqlite3 con = sqlite3.connect("mydb") +con.close() diff --git a/Doc/includes/sqlite3/connect_db_2.py b/Doc/includes/sqlite3/connect_db_2.py index f9728b36135ed75..b8a91c0dbe927e8 100644 --- a/Doc/includes/sqlite3/connect_db_2.py +++ b/Doc/includes/sqlite3/connect_db_2.py @@ -1,3 +1,4 @@ import sqlite3 con = sqlite3.connect(":memory:") +con.close() diff --git a/Doc/includes/sqlite3/countcursors.py b/Doc/includes/sqlite3/countcursors.py index ef3e70a2a9cfc5e..112f47703a2ff44 100644 --- a/Doc/includes/sqlite3/countcursors.py +++ b/Doc/includes/sqlite3/countcursors.py @@ -13,3 +13,5 @@ def cursor(self, *args, **kwargs): cur1 = con.cursor() cur2 = con.cursor() print(con.numcursors) + +con.close() diff --git a/Doc/includes/sqlite3/execsql_fetchonerow.py b/Doc/includes/sqlite3/execsql_fetchonerow.py index 078873bfc979a94..115bcb50c7c754f 100644 --- a/Doc/includes/sqlite3/execsql_fetchonerow.py +++ b/Doc/includes/sqlite3/execsql_fetchonerow.py @@ -15,3 +15,5 @@ cur.execute(SELECT) for row in cur: print('%s is %d years old.' % (row[0], row[1])) + +con.close() diff --git a/Doc/includes/sqlite3/execsql_printall_1.py b/Doc/includes/sqlite3/execsql_printall_1.py index a4ce5c528149c5c..19306e6e3ca7d18 100644 --- a/Doc/includes/sqlite3/execsql_printall_1.py +++ b/Doc/includes/sqlite3/execsql_printall_1.py @@ -11,3 +11,5 @@ # Retrieve all rows as a sequence and print that sequence: print(cur.fetchall()) + +con.close() diff --git a/Doc/includes/sqlite3/execute_1.py b/Doc/includes/sqlite3/execute_1.py index f864a8984e4e900..3466b1265a5bf24 100644 --- a/Doc/includes/sqlite3/execute_1.py +++ b/Doc/includes/sqlite3/execute_1.py @@ -14,3 +14,5 @@ cur.execute("select * from people where name_last=:who and age=:age", {"who": who, "age": age}) print(cur.fetchone()) + +con.close() diff --git a/Doc/includes/sqlite3/execute_3.py b/Doc/includes/sqlite3/execute_3.py index 0353683fc704764..608777632ea2345 100644 --- a/Doc/includes/sqlite3/execute_3.py +++ b/Doc/includes/sqlite3/execute_3.py @@ -10,3 +10,5 @@ cur.execute("select name_last, age from people where name_last=:who and age=:age", locals()) print(cur.fetchone()) + +con.close() diff --git a/Doc/includes/sqlite3/executemany_1.py b/Doc/includes/sqlite3/executemany_1.py index efae10637c7e8f0..edf6f8b7ebe61a8 100644 --- a/Doc/includes/sqlite3/executemany_1.py +++ b/Doc/includes/sqlite3/executemany_1.py @@ -22,3 +22,5 @@ def __next__(self): cur.execute("select c from characters") print(cur.fetchall()) + +con.close() diff --git a/Doc/includes/sqlite3/executemany_2.py b/Doc/includes/sqlite3/executemany_2.py index 527358ebc28e1ff..02a594c861e15ba 100644 --- a/Doc/includes/sqlite3/executemany_2.py +++ b/Doc/includes/sqlite3/executemany_2.py @@ -13,3 +13,5 @@ def char_generator(): cur.execute("select c from characters") print(cur.fetchall()) + +con.close() diff --git a/Doc/includes/sqlite3/insert_more_people.py b/Doc/includes/sqlite3/insert_more_people.py index edbc79e7e5b6cce..10cf937243f6dac 100644 --- a/Doc/includes/sqlite3/insert_more_people.py +++ b/Doc/includes/sqlite3/insert_more_people.py @@ -14,3 +14,5 @@ # The changes will not be saved unless the transaction is committed explicitly: con.commit() + +con.close() diff --git a/Doc/includes/sqlite3/load_extension.py b/Doc/includes/sqlite3/load_extension.py index b997c70668ace41..624cfe262f38b37 100644 --- a/Doc/includes/sqlite3/load_extension.py +++ b/Doc/includes/sqlite3/load_extension.py @@ -24,3 +24,5 @@ """) for row in con.execute("select rowid, name, ingredients from recipe where name match 'pie'"): print(row) + +con.close() diff --git a/Doc/includes/sqlite3/md5func.py b/Doc/includes/sqlite3/md5func.py index 0056b2d6ce84efb..16dc348bf001e26 100644 --- a/Doc/includes/sqlite3/md5func.py +++ b/Doc/includes/sqlite3/md5func.py @@ -9,3 +9,5 @@ def md5sum(t): cur = con.cursor() cur.execute("select md5(?)", (b"foo",)) print(cur.fetchone()[0]) + +con.close() diff --git a/Doc/includes/sqlite3/mysumaggr.py b/Doc/includes/sqlite3/mysumaggr.py index d2dfd2c0b98d3b8..11f96395b6c485c 100644 --- a/Doc/includes/sqlite3/mysumaggr.py +++ b/Doc/includes/sqlite3/mysumaggr.py @@ -18,3 +18,5 @@ def finalize(self): cur.execute("insert into test(i) values (2)") cur.execute("select mysum(i) from test") print(cur.fetchone()[0]) + +con.close() diff --git a/Doc/includes/sqlite3/parse_colnames.py b/Doc/includes/sqlite3/parse_colnames.py index cc68c76459eceab..5f01dbfe1cb524c 100644 --- a/Doc/includes/sqlite3/parse_colnames.py +++ b/Doc/includes/sqlite3/parse_colnames.py @@ -6,3 +6,5 @@ cur.execute('select ? as "x [timestamp]"', (datetime.datetime.now(),)) dt = cur.fetchone()[0] print(dt, type(dt)) + +con.close() diff --git a/Doc/includes/sqlite3/pysqlite_datetime.py b/Doc/includes/sqlite3/pysqlite_datetime.py index 68d49358a578b3b..5d843f906b3062d 100644 --- a/Doc/includes/sqlite3/pysqlite_datetime.py +++ b/Doc/includes/sqlite3/pysqlite_datetime.py @@ -18,3 +18,5 @@ row = cur.fetchone() print("current_date", row[0], type(row[0])) print("current_timestamp", row[1], type(row[1])) + +con.close() diff --git a/Doc/includes/sqlite3/row_factory.py b/Doc/includes/sqlite3/row_factory.py index e436ffc6c80225f..9de6e7b1b9052a3 100644 --- a/Doc/includes/sqlite3/row_factory.py +++ b/Doc/includes/sqlite3/row_factory.py @@ -11,3 +11,5 @@ def dict_factory(cursor, row): cur = con.cursor() cur.execute("select 1 as a") print(cur.fetchone()["a"]) + +con.close() diff --git a/Doc/includes/sqlite3/rowclass.py b/Doc/includes/sqlite3/rowclass.py index 92b5ad60cb57919..fc60287069a854d 100644 --- a/Doc/includes/sqlite3/rowclass.py +++ b/Doc/includes/sqlite3/rowclass.py @@ -10,3 +10,5 @@ assert row["name"] == row["nAmE"] assert row[1] == row["age"] assert row[1] == row["AgE"] + +con.close() diff --git a/Doc/includes/sqlite3/shortcut_methods.py b/Doc/includes/sqlite3/shortcut_methods.py index 71600d4f60c55ef..dfc498c14b0347b 100644 --- a/Doc/includes/sqlite3/shortcut_methods.py +++ b/Doc/includes/sqlite3/shortcut_methods.py @@ -18,3 +18,5 @@ print(row) print("I just deleted", con.execute("delete from person").rowcount, "rows") + +con.close() diff --git a/Doc/includes/sqlite3/simple_tableprinter.py b/Doc/includes/sqlite3/simple_tableprinter.py index 231d8726cd436e3..148a1707f948bc5 100644 --- a/Doc/includes/sqlite3/simple_tableprinter.py +++ b/Doc/includes/sqlite3/simple_tableprinter.py @@ -24,3 +24,5 @@ print(fieldValue.ljust(FIELD_MAX_WIDTH), end=' ') print() # Finish the row with a newline. + +con.close() diff --git a/Doc/includes/sqlite3/text_factory.py b/Doc/includes/sqlite3/text_factory.py index 5f96cdb58da1abb..a857a155cdd4ff6 100644 --- a/Doc/includes/sqlite3/text_factory.py +++ b/Doc/includes/sqlite3/text_factory.py @@ -25,3 +25,5 @@ cur.execute("select ?", ("bar",)) row = cur.fetchone() assert row[0] == "barfoo" + +con.close() From e4705ed1d56244bbacda2c38ca90efda3bdb0aa3 Mon Sep 17 00:00:00 2001 From: xtreak Date: Fri, 28 Sep 2018 22:03:17 +0530 Subject: [PATCH 5/9] Delete unused files and add comments for manually closing connections --- Doc/includes/sqlite3/connect_db_1.py | 4 ---- Doc/includes/sqlite3/connect_db_2.py | 4 ---- Doc/includes/sqlite3/ctx_manager.py | 2 ++ Doc/includes/sqlite3/execute_3.py | 14 -------------- Doc/includes/sqlite3/row_factory.py | 1 - Doc/includes/sqlite3/shortcut_methods.py | 2 ++ 6 files changed, 4 insertions(+), 23 deletions(-) delete mode 100644 Doc/includes/sqlite3/connect_db_1.py delete mode 100644 Doc/includes/sqlite3/connect_db_2.py delete mode 100644 Doc/includes/sqlite3/execute_3.py diff --git a/Doc/includes/sqlite3/connect_db_1.py b/Doc/includes/sqlite3/connect_db_1.py deleted file mode 100644 index 448e69c11c790bf..000000000000000 --- a/Doc/includes/sqlite3/connect_db_1.py +++ /dev/null @@ -1,4 +0,0 @@ -import sqlite3 - -con = sqlite3.connect("mydb") -con.close() diff --git a/Doc/includes/sqlite3/connect_db_2.py b/Doc/includes/sqlite3/connect_db_2.py deleted file mode 100644 index b8a91c0dbe927e8..000000000000000 --- a/Doc/includes/sqlite3/connect_db_2.py +++ /dev/null @@ -1,4 +0,0 @@ -import sqlite3 - -con = sqlite3.connect(":memory:") -con.close() diff --git a/Doc/includes/sqlite3/ctx_manager.py b/Doc/includes/sqlite3/ctx_manager.py index 7e9e322edf0649e..6db77d45046e1f6 100644 --- a/Doc/includes/sqlite3/ctx_manager.py +++ b/Doc/includes/sqlite3/ctx_manager.py @@ -15,4 +15,6 @@ except sqlite3.IntegrityError: print("couldn't add Joe twice") +# Connection object used as context manager only commits or rollbacks transactions, +# so the connection object should be closed manually con.close() diff --git a/Doc/includes/sqlite3/execute_3.py b/Doc/includes/sqlite3/execute_3.py deleted file mode 100644 index 608777632ea2345..000000000000000 --- a/Doc/includes/sqlite3/execute_3.py +++ /dev/null @@ -1,14 +0,0 @@ -import sqlite3 - -con = sqlite3.connect("mydb") - -cur = con.cursor() - -who = "Yeltsin" -age = 72 - -cur.execute("select name_last, age from people where name_last=:who and age=:age", - locals()) -print(cur.fetchone()) - -con.close() diff --git a/Doc/includes/sqlite3/row_factory.py b/Doc/includes/sqlite3/row_factory.py index 9de6e7b1b9052a3..6c81d1f66806524 100644 --- a/Doc/includes/sqlite3/row_factory.py +++ b/Doc/includes/sqlite3/row_factory.py @@ -11,5 +11,4 @@ def dict_factory(cursor, row): cur = con.cursor() cur.execute("select 1 as a") print(cur.fetchone()["a"]) - con.close() diff --git a/Doc/includes/sqlite3/shortcut_methods.py b/Doc/includes/sqlite3/shortcut_methods.py index dfc498c14b0347b..98a39411495cbac 100644 --- a/Doc/includes/sqlite3/shortcut_methods.py +++ b/Doc/includes/sqlite3/shortcut_methods.py @@ -19,4 +19,6 @@ print("I just deleted", con.execute("delete from person").rowcount, "rows") +# close is not a shortcut method and it's not called automatically, +# so the connection object should be closed manually con.close() From 458ef89dbf182271230fa1bc33edd05be73b6f13 Mon Sep 17 00:00:00 2001 From: xtreak Date: Fri, 28 Sep 2018 22:16:44 +0530 Subject: [PATCH 6/9] Add close to executescript, iterdump and backup examples --- Doc/includes/sqlite3/executescript.py | 1 + Doc/library/sqlite3.rst | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/Doc/includes/sqlite3/executescript.py b/Doc/includes/sqlite3/executescript.py index 7e5358178d4c0a0..aea8943fbee598f 100644 --- a/Doc/includes/sqlite3/executescript.py +++ b/Doc/includes/sqlite3/executescript.py @@ -22,3 +22,4 @@ 1987 ); """) +con.close() diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 9e3c56b5f9189e4..7a3bd70d04e7c40 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -537,6 +537,7 @@ Connection Objects with open('dump.sql', 'w') as f: for line in con.iterdump(): f.write('%s\n' % line) + con.close() .. method:: backup(target, *, pages=0, progress=None, name="main", sleep=0.250) @@ -575,6 +576,7 @@ Connection Objects con = sqlite3.connect('existing_db.db') with sqlite3.connect('backup.db') as bck: con.backup(bck, pages=1, progress=progress) + con.close() Example 2, copy an existing database into a transient copy:: @@ -583,6 +585,8 @@ Connection Objects source = sqlite3.connect('existing_db.db') dest = sqlite3.connect(':memory:') source.backup(dest) + source.close() + dest.close() Availability: SQLite 3.6.11 or higher From a15e31cafe8cdc230d6c018f33a93795af11d22a Mon Sep 17 00:00:00 2001 From: xtreak Date: Fri, 28 Sep 2018 22:48:48 +0530 Subject: [PATCH 7/9] Fix backup example to use explicit close for connection --- Doc/library/sqlite3.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 7a3bd70d04e7c40..bfa62fcc58ed2f7 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -574,8 +574,9 @@ Connection Objects print(f'Copied {total-remaining} of {total} pages...') con = sqlite3.connect('existing_db.db') - with sqlite3.connect('backup.db') as bck: - con.backup(bck, pages=1, progress=progress) + bck = sqlite3.connect('backup.db') + con.backup(bck, pages=1, progress=progress) + bck.close() con.close() Example 2, copy an existing database into a transient copy:: From 89def502b9cb9f6c375fb1e865e12f0d376faa08 Mon Sep 17 00:00:00 2001 From: xtreak Date: Fri, 28 Sep 2018 23:00:07 +0530 Subject: [PATCH 8/9] Use context manager in backup example for transaction support --- Doc/library/sqlite3.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index bfa62fcc58ed2f7..6141c45513903fe 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -575,7 +575,8 @@ Connection Objects con = sqlite3.connect('existing_db.db') bck = sqlite3.connect('backup.db') - con.backup(bck, pages=1, progress=progress) + with bck: + con.backup(bck, pages=1, progress=progress) bck.close() con.close() @@ -586,8 +587,6 @@ Connection Objects source = sqlite3.connect('existing_db.db') dest = sqlite3.connect(':memory:') source.backup(dest) - source.close() - dest.close() Availability: SQLite 3.6.11 or higher From 539a36117dc327616516c3ba8ef64891b44a9769 Mon Sep 17 00:00:00 2001 From: Berker Peksag Date: Mon, 20 May 2019 00:39:45 +0300 Subject: [PATCH 9/9] Update row_factory.py --- Doc/includes/sqlite3/row_factory.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Doc/includes/sqlite3/row_factory.py b/Doc/includes/sqlite3/row_factory.py index 6c81d1f66806524..9de6e7b1b9052a3 100644 --- a/Doc/includes/sqlite3/row_factory.py +++ b/Doc/includes/sqlite3/row_factory.py @@ -11,4 +11,5 @@ def dict_factory(cursor, row): cur = con.cursor() cur.execute("select 1 as a") print(cur.fetchone()["a"]) + con.close()