From 1594f58f92c23658a199a690e55d8ae03182affd Mon Sep 17 00:00:00 2001 From: Matt Hutton Date: Sun, 23 Feb 2025 10:41:15 +1300 Subject: [PATCH 1/3] Revert "fix: Improve query performance by using a single connection" This reverts commit 0ed2f9db1de284fcff13e6afba2fd3fa2e086477. This addresses a CI test warning: 'ResourceWarning: unclosed database'. --- things/database.py | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/things/database.py b/things/database.py index 5bbd7da..ab0a050 100755 --- a/things/database.py +++ b/things/database.py @@ -168,7 +168,6 @@ class Database: """ debug = False - connection: sqlite3.Connection # pylint: disable=R0913 def __init__(self, filepath=None, print_sql=False): @@ -182,11 +181,6 @@ def __init__(self, filepath=None, print_sql=False): if self.print_sql: self.execute_query_count = 0 - # "ro" means read-only - # See: https://sqlite.org/uri.html#recognized_query_parameters - uri = f"file:{self.filepath}?mode=ro" - self.connection = sqlite3.connect(uri, uri=True) # pylint: disable=E1101 - # Test for migrated database in Things 3.15.16+ # -------------------------------- assert self.get_version() > 21, ( @@ -501,14 +495,17 @@ def execute_query(self, sql_query, parameters=(), row_factory=None): print(prettify_sql(sql_query)) print() - with self.connection: - # Using context manager to keep queries in separate transactions, - # see https://docs.python.org/3/library/sqlite3.html#sqlite3-connection-context-manager - self.connection.row_factory = row_factory or dict_factory - cursor = self.connection.cursor() - cursor.execute(sql_query, parameters) + # "ro" means read-only + # See: https://sqlite.org/uri.html#recognized_query_parameters + uri = f"file:{self.filepath}?mode=ro" + connection = sqlite3.connect(uri, uri=True) # pylint: disable=E1101 + connection.row_factory = row_factory or dict_factory + cursor = connection.cursor() + cursor.execute(sql_query, parameters) - return cursor.fetchall() + result = cursor.fetchall() + connection.close() + return result # Helper functions From cca936f20e6491cc3c35802432967f0cdfbef50a Mon Sep 17 00:00:00 2001 From: Matt Hutton Date: Sun, 23 Feb 2025 10:54:55 +1300 Subject: [PATCH 2/3] Reapply "fix: Improve query performance by using a single connection" This reverts commit 1594f58f92c23658a199a690e55d8ae03182affd. --- things/database.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/things/database.py b/things/database.py index ab0a050..5bbd7da 100755 --- a/things/database.py +++ b/things/database.py @@ -168,6 +168,7 @@ class Database: """ debug = False + connection: sqlite3.Connection # pylint: disable=R0913 def __init__(self, filepath=None, print_sql=False): @@ -181,6 +182,11 @@ def __init__(self, filepath=None, print_sql=False): if self.print_sql: self.execute_query_count = 0 + # "ro" means read-only + # See: https://sqlite.org/uri.html#recognized_query_parameters + uri = f"file:{self.filepath}?mode=ro" + self.connection = sqlite3.connect(uri, uri=True) # pylint: disable=E1101 + # Test for migrated database in Things 3.15.16+ # -------------------------------- assert self.get_version() > 21, ( @@ -495,17 +501,14 @@ def execute_query(self, sql_query, parameters=(), row_factory=None): print(prettify_sql(sql_query)) print() - # "ro" means read-only - # See: https://sqlite.org/uri.html#recognized_query_parameters - uri = f"file:{self.filepath}?mode=ro" - connection = sqlite3.connect(uri, uri=True) # pylint: disable=E1101 - connection.row_factory = row_factory or dict_factory - cursor = connection.cursor() - cursor.execute(sql_query, parameters) + with self.connection: + # Using context manager to keep queries in separate transactions, + # see https://docs.python.org/3/library/sqlite3.html#sqlite3-connection-context-manager + self.connection.row_factory = row_factory or dict_factory + cursor = self.connection.cursor() + cursor.execute(sql_query, parameters) - result = cursor.fetchall() - connection.close() - return result + return cursor.fetchall() # Helper functions From 0b2646304549871499771f9ed2845c8ce791f5c9 Mon Sep 17 00:00:00 2001 From: Matt Hutton Date: Sun, 23 Feb 2025 11:30:15 +1300 Subject: [PATCH 3/3] DRAFT: close DB connection in a weakref.finalize step --- things/database.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/things/database.py b/things/database.py index 5bbd7da..e5fcce4 100755 --- a/things/database.py +++ b/things/database.py @@ -10,6 +10,7 @@ import sqlite3 from textwrap import dedent from typing import Optional, Union +import weakref # -------------------------------------------------- @@ -186,6 +187,7 @@ def __init__(self, filepath=None, print_sql=False): # See: https://sqlite.org/uri.html#recognized_query_parameters uri = f"file:{self.filepath}?mode=ro" self.connection = sqlite3.connect(uri, uri=True) # pylint: disable=E1101 + self._finalizer = weakref.finalize(self, self._close_connection) # Test for migrated database in Things 3.15.16+ # -------------------------------- @@ -510,6 +512,10 @@ def execute_query(self, sql_query, parameters=(), row_factory=None): return cursor.fetchall() + def _close_connection(self): + """Close the database connection.""" + self.connection.close() + # Helper functions