Masalahnya di sini bagaimana sqlalchemy memutuskan untuk mengeluarkan komit setelah setiap pernyataan.
jika sebuah teks diteruskan ke engine.execute
, sqlalchemy akan mencoba menentukan apakah teks adalah DML atau DDL menggunakan ekspresi reguler berikut. Anda dapat menemukannya di sumber di sini
AUTOCOMMIT_REGEXP = re.compile(
r"\s*(?:UPDATE|INSERT|CREATE|DELETE|DROP|ALTER)", re.I | re.UNICODE
)
Ini hanya mendeteksi kata-kata jika mereka berada di awal teks, mengabaikan spasi putih di depan. Jadi, saat percobaan pertama Anda # works fine
, contoh kedua gagal mengenali bahwa komit perlu dikeluarkan setelah pernyataan dieksekusi karena kata pertama adalah SET
.
Sebagai gantinya, sqlalchemy mengeluarkan rollback, sehingga # appears to succeed/does NOT throw any error
.
solusi paling sederhana adalah secara manual melakukan.
contoh:
engine.execute("SET ROLE read_write; CREATE table testpublic (id int, val text); COMMIT;")
atau, bungkus sql dalam text
dan atur autocommit=True
, seperti yang ditunjukkan dalam dokumentasi
stmt = text('set role read_write; create table testpublic (id int, val text);').execution_options(autocommit=True)
e.execute(stmt)