@@ -400,6 +400,8 @@ def render_literal_value(self, value, type_):
400
400
401
401
402
402
class SnowflakeExecutionContext (default .DefaultExecutionContext ):
403
+ INSERT_SQL_RE = re .compile (r"^insert\s+into" , flags = re .IGNORECASE )
404
+
403
405
def fire_sequence (self , seq , type_ ):
404
406
return self ._execute_scalar (
405
407
f"SELECT { self .identifier_preparer .format_sequence (seq )} .nextval" ,
@@ -425,7 +427,7 @@ def should_autocommit(self):
425
427
return autocommit and not self .isddl
426
428
427
429
def pre_exec (self ):
428
- if self .compiled :
430
+ if self .compiled and self . identifier_preparer . _double_percents :
429
431
# for compiled statements, percent is doubled for escape, we turn on _interpolate_empty_sequences
430
432
if hasattr (self ._dbapi_connection , "driver_connection" ):
431
433
# _dbapi_connection is a _ConnectionFairy which proxies raw SnowflakeConnection
@@ -436,8 +438,15 @@ def pre_exec(self):
436
438
# _dbapi_connection is a raw SnowflakeConnection
437
439
self ._dbapi_connection ._interpolate_empty_sequences = True
438
440
441
+ # if the statement is executemany insert, setting _interpolate_empty_sequences to True is not enough,
442
+ # because executemany pre-processes the param binding and then pass None params to execute so
443
+ # _interpolate_empty_sequences condition not getting met for the command.
444
+ # Therefore, we manually revert the escape percent in the command here
445
+ if self .executemany and self .INSERT_SQL_RE .match (self .statement ):
446
+ self .statement = self .statement .replace ("%%" , "%" )
447
+
439
448
def post_exec (self ):
440
- if self .compiled :
449
+ if self .compiled and self . identifier_preparer . _double_percents :
441
450
# for compiled statements, percent is doubled for escapeafter execution
442
451
# we reset _interpolate_empty_sequences to false which is turned on in pre_exec
443
452
if hasattr (self ._dbapi_connection , "driver_connection" ):
0 commit comments