Sejauh yang saya tahu, tidak ada cara agar ORM mengeluarkan sisipan massal. Saya percaya alasan yang mendasarinya adalah bahwa SQLAlchemy perlu melacak identitas setiap objek (yaitu, kunci primer baru), dan sisipan massal mengganggu itu. Misalnya, dengan asumsi foo
tabel Anda berisi id
kolom dan dipetakan ke Foo
kelas:
x = Foo(bar=1)
print x.id
# None
session.add(x)
session.flush()
# BEGIN
# INSERT INTO foo (bar) VALUES(1)
# COMMIT
print x.id
# 1
Karena SQLAlchemy mengambil nilainya x.id
tanpa mengeluarkan kueri lain, kita dapat menyimpulkan bahwa SQLAlchemy mendapatkan nilainya langsung dari INSERT
pernyataan. Jika Anda tidak memerlukan akses berikutnya ke objek yang dibuat melalui instance yang sama , Anda dapat melewati lapisan ORM untuk penyisipan Anda:
Foo.__table__.insert().execute([{'bar': 1}, {'bar': 2}, {'bar': 3}])
# INSERT INTO foo (bar) VALUES ((1,), (2,), (3,))
SQLAlchemy tidak dapat mencocokkan baris baru ini dengan objek yang sudah ada, jadi Anda harus menanyakannya lagi untuk operasi selanjutnya.
Sejauh menyangkut data usang, perlu diingat bahwa sesi tidak memiliki cara bawaan untuk mengetahui kapan database diubah di luar sesi. Untuk mengakses data yang diubah secara eksternal melalui instance yang ada, instance tersebut harus ditandai sebagai kedaluwarsa . Ini terjadi secara default aktif session.commit()
, tetapi dapat dilakukan secara manual dengan menelepon session.expire_all()
atau session.expire(instance)
. Contoh (SQL dihilangkan):
x = Foo(bar=1)
session.add(x)
session.commit()
print x.bar
# 1
foo.update().execute(bar=42)
print x.bar
# 1
session.expire(x)
print x.bar
# 42
session.commit()
kedaluwarsa x
, jadi pernyataan cetak pertama secara implisit membuka transaksi baru dan x
atribut kueri ulang . Jika Anda mengomentari pernyataan cetak pertama, Anda akan melihat bahwa yang kedua sekarang mengambil nilai yang benar, karena kueri baru tidak dikeluarkan hingga setelah pembaruan.
Ini masuk akal dari sudut pandang isolasi transaksional - Anda hanya boleh mengambil modifikasi eksternal antar transaksi. Jika hal ini menyebabkan masalah bagi Anda, saya sarankan untuk mengklarifikasi atau memikirkan ulang batasan transaksi aplikasi Anda daripada segera meraihnya session.expire_all()
.