Das Problem hier, wie sqlalchemy entscheidet, nach jeder Anweisung ein Commit auszugeben.
wenn ein Text an engine.execute
übergeben wird , versucht sqlalchemy mithilfe der folgenden Regex festzustellen, ob es sich bei dem Text um eine DML oder DDL handelt. Sie finden es in den Quellen hier
AUTOCOMMIT_REGEXP = re.compile(
r"\s*(?:UPDATE|INSERT|CREATE|DELETE|DROP|ALTER)", re.I | re.UNICODE
)
Dadurch werden die Wörter nur erkannt, wenn sie am Anfang des Textes stehen, wobei alle führenden Leerzeichen ignoriert werden. Also, während Ihr erster Versuch # works fine
, erkennt das zweite Beispiel nicht, dass ein Commit ausgegeben werden muss, nachdem die Anweisung ausgeführt wurde, da das erste Wort SET
ist .
Stattdessen gibt sqlalchemy ein Rollback aus, sodass es # appears to succeed/does NOT throw any error
.
Die einfachste Lösung ist das manuelle Commit.
Beispiel:
engine.execute("SET ROLE read_write; CREATE table testpublic (id int, val text); COMMIT;")
oder schließen Sie die SQL in text
ein und setzen Sie autocommit=True
, wie in der Dokumentation gezeigt
stmt = text('set role read_write; create table testpublic (id int, val text);').execution_options(autocommit=True)
e.execute(stmt)