Skip to content

Commit

Permalink
fix: Improve query performance by using a single connection
Browse files Browse the repository at this point in the history
Use one connection for the lifetime of the process rather
than creating a new connection for each query.

This cuts execution time roughtly in half for queries
across large Things databases.
  • Loading branch information
mbhutton authored and AlexanderWillner committed Nov 10, 2024
1 parent 681cb8b commit 0ed2f9d
Showing 1 changed file with 13 additions and 10 deletions.
23 changes: 13 additions & 10 deletions things/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ class Database:
"""

debug = False
connection: sqlite3.Connection

# pylint: disable=R0913
def __init__(self, filepath=None, print_sql=False):
Expand All @@ -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, (
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 0ed2f9d

Please sign in to comment.