diff --git a/synapse/storage/database.py b/synapse/storage/database.py
index 226ccc1671..1f5f5eb6f8 100644
--- a/synapse/storage/database.py
+++ b/synapse/storage/database.py
@@ -58,7 +58,7 @@ from synapse.metrics import register_threadpool
from synapse.metrics.background_process_metrics import run_as_background_process
from synapse.storage.background_updates import BackgroundUpdater
from synapse.storage.engines import BaseDatabaseEngine, PostgresEngine, Sqlite3Engine
-from synapse.storage.types import Connection, Cursor
+from synapse.storage.types import Connection, Cursor, SQLQueryParameters
from synapse.util.async_helpers import delay_cancellation
from synapse.util.iterutils import batch_iter
@@ -371,10 +371,18 @@ class LoggingTransaction:
if isinstance(self.database_engine, PostgresEngine):
from psycopg2.extras import execute_batch
+ # TODO: is it safe for values to be Iterable[Iterable[Any]] here?
+ # https://www.psycopg.org/docs/extras.html?highlight=execute_batch#psycopg2.extras.execute_batch
+ # suggests each arg in args should be a sequence or mapping
self._do_execute(
lambda the_sql: execute_batch(self.txn, the_sql, args), sql
)
else:
+ # TODO: is it safe for values to be Iterable[Iterable[Any]] here?
+ # https://docs.python.org/3/library/sqlite3.html?highlight=sqlite3#sqlite3.Cursor.executemany
+ # suggests that the outer collection may be iterable, but
+ # https://docs.python.org/3/library/sqlite3.html?highlight=sqlite3#how-to-use-placeholders-to-bind-values-in-sql-queries
+ # suggests that the inner collection should be a sequence or dict.
self.executemany(sql, args)
def execute_values(
@@ -390,14 +398,20 @@ class LoggingTransaction:
from psycopg2.extras import execute_values
return self._do_execute(
+ # TODO: is it safe for values to be Iterable[Iterable[Any]] here?
+ # https://www.psycopg.org/docs/extras.html?highlight=execute_batch#psycopg2.extras.execute_values says values should be Sequence[Sequence]
lambda the_sql: execute_values(self.txn, the_sql, values, fetch=fetch),
sql,
)
- def execute(self, sql: str, *args: Any) -> None:
- self._do_execute(self.txn.execute, sql, *args)
+ def execute(self, sql: str, parameters: SQLQueryParameters = ()) -> None:
+ self._do_execute(self.txn.execute, sql, parameters)
def executemany(self, sql: str, *args: Any) -> None:
+ # TODO: we should add a type for *args here. Looking at Cursor.executemany
+ # and DBAPI2 it ought to be Sequence[_Parameter], but we pass in
+ # Iterable[Iterable[Any]] in execute_batch and execute_values above, which mypy
+ # complains about.
self._do_execute(self.txn.executemany, sql, *args)
def executescript(self, sql: str) -> None:
|