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)