Le problème ici est de savoir comment sqlalchemy décide d'émettre un commit après chaque instruction.
si un texte est passé à engine.execute
, sqlalchemy tentera de déterminer si le texte est un DML ou un DDL à l'aide de l'expression régulière suivante. Vous pouvez le trouver dans les sources ici
AUTOCOMMIT_REGEXP = re.compile(
r"\s*(?:UPDATE|INSERT|CREATE|DELETE|DROP|ALTER)", re.I | re.UNICODE
)
Cela ne détecte les mots que s'ils se trouvent au début du texte, en ignorant les espaces en début de texte. Ainsi, alors que votre première tentative # works fine
, le deuxième exemple ne parvient pas à reconnaître qu'un commit doit être émis après l'exécution de l'instruction car le premier mot est SET
.
Au lieu de cela, sqlalchemy émet une annulation, de sorte qu'il # appears to succeed/does NOT throw any error
.
la solution la plus simple est de valider manuellement.
exemple :
engine.execute("SET ROLE read_write; CREATE table testpublic (id int, val text); COMMIT;")
ou enveloppez le sql dans text
et définissez autocommit=True
, comme indiqué dans la documentation
stmt = text('set role read_write; create table testpublic (id int, val text);').execution_options(autocommit=True)
e.execute(stmt)