Kwestia tutaj, w jaki sposób sqlalchemy decyduje się wydać zatwierdzenie po każdej instrukcji.
jeśli tekst jest przekazywany do engine.execute , sqlalchemy spróbuje określić, czy tekst jest DML, czy DDL, używając następującego wyrażenia regularnego. Znajdziesz go w źródłach tutaj
AUTOCOMMIT_REGEXP = re.compile(
r"\s*(?:UPDATE|INSERT|CREATE|DELETE|DROP|ALTER)", re.I | re.UNICODE
)
Wykrywa słowa tylko wtedy, gdy znajdują się na początku tekstu, ignorując wszelkie początkowe spacje. Tak więc, podczas gdy Twoja pierwsza próba # works fine , drugi przykład nie rozpoznaje, że zatwierdzenie musi zostać wydane po wykonaniu instrukcji, ponieważ pierwsze słowo to SET .
Zamiast tego sqlalchemy wycofuje, więc # appears to succeed/does NOT throw any error .
najprostszym rozwiązaniem jest ręczne zatwierdzenie.
przykład:
engine.execute("SET ROLE read_write; CREATE table testpublic (id int, val text); COMMIT;")
lub zawinąć sql w text i ustaw autocommit=True , jak pokazano w dokumentacji
stmt = text('set role read_write; create table testpublic (id int, val text);').execution_options(autocommit=True)
e.execute(stmt)