Mengapa memerah jika Anda dapat melakukan?
Sebagai seseorang yang baru bekerja dengan database dan sqlalchemy, jawaban sebelumnya - yang flush()
mengirimkan pernyataan SQL ke DB dan commit()
tetap ada - tidak jelas bagi saya. Definisi tersebut masuk akal tetapi tidak segera jelas dari definisi mengapa Anda akan menggunakan flush alih-alih hanya melakukan.
Karena komit selalu memerah ( https://docs.sqlalchemy.org/en/13/orm/session_basics.html#committing ) suara ini sangat mirip. Saya pikir masalah besar untuk disoroti adalah bahwa flush tidak permanen dan dapat dibatalkan, sedangkan komit adalah permanen, dalam arti bahwa Anda tidak dapat meminta database untuk membatalkan komit terakhir (saya pikir)
@snapshoe menyoroti bahwa jika Anda ingin query database dan mendapatkan hasil yang menyertakan objek yang baru ditambahkan, Anda harus terlebih dahulu memerah (atau melakukan, yang akan memerah untuk Anda). Mungkin ini berguna untuk beberapa orang walaupun saya tidak yakin mengapa Anda ingin memerah daripada melakukan komitmen (selain dari jawaban sepele yang dapat dibatalkan).
Dalam contoh lain saya sedang menyinkronkan dokumen antara DB lokal dan server jauh, dan jika pengguna memutuskan untuk membatalkan, semua penambahan / pembaruan / penghapusan harus dibatalkan (yaitu tidak ada sinkronisasi parsial, hanya sinkronisasi penuh). Saat memperbarui satu dokumen, saya memutuskan untuk menghapus baris lama dan menambahkan versi yang diperbarui dari server jarak jauh. Ternyata karena cara sqlalchemy ditulis, urutan operasi saat melakukan tidak dijamin. Ini menghasilkan menambahkan versi duplikat (sebelum mencoba menghapus yang lama), yang mengakibatkan DB gagal kendala unik. Untuk menyiasati ini saya menggunakan flush()
agar pesanan tetap dipertahankan, tetapi saya masih bisa membatalkan jika nanti proses sinkronisasi gagal.
Lihat posting saya tentang ini di: Apakah ada pesanan untuk tambah versus hapus ketika melakukan dalam sqlalchemy
Demikian pula, seseorang ingin tahu apakah pesanan ditambahkan dipertahankan ketika melakukan, yaitu jika saya tambahkan object1
kemudian tambahkan object2
, apakah object1
ditambahkan ke database sebelum object2
Apakah SQLAlchemy menyimpan pesanan ketika menambahkan objek ke sesi?
Sekali lagi, di sini mungkin penggunaan flush () akan memastikan perilaku yang diinginkan. Jadi secara ringkas, satu penggunaan untuk flush adalah untuk memberikan jaminan pesanan (saya pikir), sekali lagi sambil tetap membiarkan diri Anda opsi "undo" yang komit tidak menyediakan.
Autoflush dan Autocommit
Catatan, autoflush dapat digunakan untuk memastikan kueri bertindak pada basis data yang diperbarui karena sqlalchemy akan memerah sebelum menjalankan kueri. https://docs.sqlalchemy.org/en/13/orm/session_api.html#sqlalchemy.orm.session.Session.params.autoflush
Autocommit adalah hal lain yang saya tidak sepenuhnya mengerti tetapi sepertinya penggunaannya tidak disarankan:
https://docs.sqlalchemy.org/en/13/orm/session_api.html#sqlalchemy.orm.session.Session.params. komentar otomatis
Penggunaan Memori
Sekarang pertanyaan awal sebenarnya ingin tahu tentang dampak flush vs commit untuk tujuan memori. Karena kemampuan untuk bertahan atau tidak adalah sesuatu yang ditawarkan oleh basis data (saya pikir), hanya pembilasan harus cukup untuk membongkar ke basis data - meskipun melakukan itu tidak akan merugikan (sebenarnya mungkin membantu - lihat di bawah) jika Anda tidak peduli tentang kehancuran .
sqlalchemy menggunakan referensi lemah untuk objek yang telah memerah: https://docs.sqlalchemy.org/en/13/orm/session_state_management.html#session-referencing-behavior
Ini berarti jika Anda tidak memiliki objek yang secara eksplisit dipegang di suatu tempat, seperti dalam daftar atau dikt, sqlalchemy tidak akan menyimpannya di memori.
Namun, kemudian Anda memiliki sisi database yang perlu dikhawatirkan. Agaknya pembilasan tanpa komitmen disertai dengan penalti memori untuk mempertahankan transaksi. Sekali lagi, saya baru dalam hal ini, tetapi di sini ada tautan yang tampaknya menyarankan hal ini: https://stackoverflow.com/a/15305650/764365
Dengan kata lain, komit harus mengurangi penggunaan memori, meskipun mungkin ada trade-off antara memori dan kinerja di sini. Dengan kata lain, Anda mungkin tidak ingin melakukan perubahan database tunggal, satu per satu (karena alasan kinerja), tetapi menunggu terlalu lama akan meningkatkan penggunaan memori.