From: Yuval Dinari <> Date: Wed, 17 Jul 2019 14:44:18 +0000 (+0300) Subject: - Create new flag, execution_mode, to replace use_batch_mode, that more correctly... X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8e782bfc8f8c5675da4a8c1c16ff3291e5320a53;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - Create new flag, execution_mode, to replace use_batch_mode, that more correctly reflects the controlled behavior - When flag indicates using psycopg2.execute_values but query is not insert, use psycopg2.execute_batch (and not the slow psycopg2.executemany) Fixes: #4623 --- diff --git a/lib/sqlalchemy/dialects/postgresql/psycopg2.py b/lib/sqlalchemy/dialects/postgresql/psycopg2.py index 904995593e..94e8f289a8 100644 --- a/lib/sqlalchemy/dialects/postgresql/psycopg2.py +++ b/lib/sqlalchemy/dialects/postgresql/psycopg2.py @@ -52,6 +52,21 @@ psycopg2-specific keyword arguments which are accepted by :ref:`psycopg2_unicode` +* ``execution_mode``: This flag determines the psycopg2 methods used for executing queries, + enabling faster execution for queries with multiple parameters. It replaces use_batch_mode + (which is still supported for backward compatibility). + Possible values are: + None - Flag not used, ``use_batch_mode`` determines behavior + 'single_statement' - Every parameters set is a single query that is sent to the database. + Uses ``psycopg2.extras.execute`` or ``psycopg2.extras.executemany``. + Equivalent to use_batch_mode=False + 'statements_batch' - Multiple queries are sent together to the database. + Uses ``psycopg2.extras.execute_batch``. + Equivalent to use_batch_mode=True. + 'values_batch' - Multiple parameters sets are packed together into a single query that is sent to the database. + This flag currently supports only insert queries, and uses ``psycopg2.extras.execute_values``. + For other queries it behaves the same as 'statements_batch'. + * ``use_batch_mode``: This flag allows using psycopg2 faster methods for executing queries with multiple parameters (usually INSERT queries). If equals True or 'execute_batch', ``psycopg2.extras.execute_batch`` is used. @@ -647,6 +662,7 @@ class PGDialect_psycopg2(PGDialect): client_encoding=None, use_native_hstore=True, use_native_uuid=True, + execution_mode=None, use_batch_mode=False, **kwargs ): @@ -657,7 +673,14 @@ class PGDialect_psycopg2(PGDialect): self.use_native_uuid = use_native_uuid self.supports_unicode_binds = use_native_unicode self.client_encoding = client_encoding + self.psycopg2_execution_mode = execution_mode self.psycopg2_batch_mode = use_batch_mode + + # use_batch_mode supported for backward compatibility. To avoid having to check two flags, + # set execution_mode flag here and use it only + if not self.psycopg2_execution_mode: + self.psycopg2_execution_mode = 'statements_batch' if self.psycopg2_batch_mode else 'single_statement' + if self.dbapi and hasattr(self.dbapi, "__version__"): m = re.match(r"(\d+)\.(\d+)(?:\.(\d+))?", self.dbapi.__version__) if m: @@ -682,7 +705,7 @@ class PGDialect_psycopg2(PGDialect): self.supports_sane_multi_rowcount = ( self.psycopg2_version >= self.FEATURE_VERSION_MAP["sane_multi_rowcount"] - and not self.psycopg2_batch_mode + and self.psycopg2_execution_mode == 'single_statement' ) @classmethod @@ -803,18 +826,21 @@ class PGDialect_psycopg2(PGDialect): return None def do_executemany(self, cursor, statement, parameters, context=None): - if self.psycopg2_batch_mode == 'execute_values' and context and context.compiled.execute_values_insert_template: + if self.psycopg2_execution_mode == 'single_insert': + cursor.executemany(statement, parameters) + elif self.psycopg2_execution_mode == 'values_batch' and \ + context and \ + context.compiled.execute_values_insert_template: + self._psycopg2_extras().execute_values( cursor, statement, parameters, template=context.compiled.execute_values_insert_template, page_size=context.compiled.execute_values_page_size) - # Support True for backward compatibility - elif self.psycopg2_batch_mode in ('execute_batch', True): + + else: # 'values_batch' of non-insert query, or 'statements_batch' self._psycopg2_extras().execute_batch(cursor, statement, parameters) - else: - cursor.executemany(statement, parameters) @util.memoized_instancemethod def _hstore_oids(self, conn):