ここでの問題は、sqlalchemyが各ステートメントの後にコミットを発行することを決定する方法です。
テキストがengine.execute
に渡された場合 、sqlalchemyは、次の正規表現を使用して、テキストがDMLであるかDDLであるかを判別しようとします。こちらのソースで見つけることができます
AUTOCOMMIT_REGEXP = re.compile(
r"\s*(?:UPDATE|INSERT|CREATE|DELETE|DROP|ALTER)", re.I | re.UNICODE
)
これは、単語がテキストの先頭にある場合にのみ単語を検出し、先頭の空白を無視します。したがって、最初の試行では# works fine
、2番目の例では、最初の単語がSET
であるため、ステートメントの実行後にコミットを発行する必要があることを認識できません。 。
代わりに、sqlalchemyはロールバックを発行するため、# appears to succeed/does NOT throw any error
。
最も簡単な解決策は、手動でコミットすることです。
例:
engine.execute("SET ROLE read_write; CREATE table testpublic (id int, val text); COMMIT;")
または、SQLをtext
でラップします autocommit=True
を設定します 、ドキュメントに示されているように
stmt = text('set role read_write; create table testpublic (id int, val text);').execution_options(autocommit=True)
e.execute(stmt)