fix: _get_runtime_limit must apply to the right alias

instead of just returning the value for the default alias

that this wasn't done was a bug generally (the per-alias limits
simply didn't apply) but was exposed when running the CI against
non-sqlite databases, because in that setup the main database
would not get a limit set, but because the getter fell back
to the default (which wasn't set) there was an exception.
This commit is contained in:
Klaas van Schelven
2025-05-06 21:45:41 +02:00
parent 474c677f12
commit 699f6e587d

View File

@@ -46,7 +46,7 @@ def _set_runtime_limit(using, is_default_for_connection, seconds):
) )
def _get_runtime_limit(using=None): def _get_runtime_limit(using):
if using is None: if using is None:
using = DEFAULT_DB_ALIAS using = DEFAULT_DB_ALIAS
@@ -80,12 +80,12 @@ def different_runtime_limit(seconds, using=None):
@contextmanager @contextmanager
def limit_runtime(conn, query=None, params=None): def limit_runtime(alias, conn, query=None, params=None):
# query & params are only used for logging purposes; they are not used to actually limit the runtime. # query & params are only used for logging purposes; they are not used to actually limit the runtime.
start = time.time() start = time.time()
def check_time(): def check_time():
if time.time() > start + _get_runtime_limit(): if time.time() > start + _get_runtime_limit(alias):
return 1 return 1
return 0 return 0
@@ -98,7 +98,7 @@ def limit_runtime(conn, query=None, params=None):
yield yield
if time.time() > start + _get_runtime_limit() + 0.01: if time.time() > start + _get_runtime_limit(alias) + 0.01:
# https://sqlite.org/forum/forumpost/fa65709226 to see why we need this. # https://sqlite.org/forum/forumpost/fa65709226 to see why we need this.
# #
# Doing an actual timeout _now_ doesn't achieve anything (the goal is generally to avoid things taking too long, # Doing an actual timeout _now_ doesn't achieve anything (the goal is generally to avoid things taking too long,
@@ -156,23 +156,29 @@ class DatabaseWrapper(UnpatchedDatabaseWrapper):
# return PrintOnClose(result) # return PrintOnClose(result)
def create_cursor(self, name=None): def create_cursor(self, name=None):
return self.connection.cursor(factory=SQLiteCursorWrapper) return self.connection.cursor(factory=get_sqlite_cursor_wrapper(self.alias))
class SQLiteCursorWrapper(UnpatchedSQLiteCursorWrapper): def get_sqlite_cursor_wrapper(alias):
if alias is None:
alias = DEFAULT_DB_ALIAS
def execute(self, query, params=None): class SQLiteCursorWrapper(UnpatchedSQLiteCursorWrapper):
if settings.I_AM_RUNNING == "MIGRATE":
# migrations in Sqlite are often slow (drop/recreate tables, etc); so we don't want to limit them
return super().execute(query, params)
with limit_runtime(self.connection, query=query, params=params): def execute(self, query, params=None):
return super().execute(query, params) if settings.I_AM_RUNNING == "MIGRATE":
# migrations in Sqlite are often slow (drop/recreate tables, etc); so we don't want to limit them
return super().execute(query, params)
def executemany(self, query, param_list): with limit_runtime(alias, self.connection, query=query, params=params):
if settings.I_AM_RUNNING == "MIGRATE": return super().execute(query, params)
# migrations in Sqlite are often slow (drop/recreate tables, etc); so we don't want to limit them
return super().executemany(query, param_list)
with limit_runtime(self.connection, query=query, params=param_list): def executemany(self, query, param_list):
return super().executemany(query, param_list) if settings.I_AM_RUNNING == "MIGRATE":
# migrations in Sqlite are often slow (drop/recreate tables, etc); so we don't want to limit them
return super().executemany(query, param_list)
with limit_runtime(alias, self.connection, query=query, params=param_list):
return super().executemany(query, param_list)
return SQLiteCursorWrapper