sessionmaker()
adalah sebuah pabrik, itu ada untuk mendorong penempatan opsi konfigurasi untuk membuat Session
objek baru hanya di satu tempat. Ini opsional, karena Anda dapat dengan mudah menelepon Session(bind=engine, expire_on_commit=False)
kapan pun Anda membutuhkan yang baru Session
, kecuali yang verbose dan mubazir, dan saya ingin menghentikan penyebaran "pembantu" skala kecil yang masing-masing mendekati masalah redundansi ini di beberapa dan cara yang lebih membingungkan.
Jadi sessionmaker()
hanyalah alat untuk membantu Anda membuat Session
objek saat Anda membutuhkannya.
Bagian selanjutnya. Saya pikir pertanyaannya adalah, apa perbedaan antara membuat yang baru Session()
di berbagai titik versus hanya menggunakan satu sepenuhnya. Jawabannya, tidak terlalu banyak. Session
adalah wadah untuk semua objek yang Anda masukkan ke dalamnya, dan kemudian juga melacak transaksi terbuka. Pada saat Anda menelepon rollback()
atau commit()
, transaksi selesai, dan Session
tidak memiliki koneksi ke database hingga dipanggil untuk mengeluarkan SQL lagi. Tautan yang dipegangnya ke objek yang dipetakan adalah referensi yang lemah, asalkan objek bersih dari perubahan yang tertunda, bahkan dalam hal itu Session
kehendak akan mengosongkan dirinya kembali ke keadaan baru ketika aplikasi Anda kehilangan semua referensi ke objek yang dipetakan. Jika Anda membiarkannya dengan default"expire_on_commit"
pengaturan, maka semua objek kedaluwarsa setelah komit. Jika itu Session
hang sekitar selama lima atau dua puluh menit, dan semua jenis hal telah berubah dalam database saat Anda menggunakannya lagi, itu akan memuat semua status baru saat Anda mengakses objek itu lagi meskipun mereka telah duduk di memori selama dua puluh menit.
Dalam aplikasi web, kami biasanya berkata, hai mengapa Anda tidak membuat yang baru Session
di setiap permintaan, daripada menggunakan yang sama berulang kali. Praktik ini memastikan bahwa permintaan baru mulai "bersih". Jika beberapa objek dari permintaan sebelumnya belum dikumpulkan sampah, dan jika Anda telah menonaktifkan "expire_on_commit"
, mungkin beberapa status dari permintaan sebelumnya masih berkeliaran, dan bahkan mungkin cukup lama. Jika Anda berhati-hati untuk membiarkan expire_on_commit
menyala dan pasti menelepon commit()
atau rollback()
atas permintaan, maka tidak apa-apa, tetapi jika Anda memulai dengan yang baru Session
, maka tidak ada pertanyaan bahwa Anda mulai bersih. Jadi ide untuk memulai setiap permintaan dengan yang baruSession
sebenarnya hanyalah cara paling sederhana untuk memastikan Anda memulai dari awal, dan membuat penggunaan expire_on_commit
cukup banyak opsional, karena tanda ini dapat menyebabkan banyak SQL tambahan untuk operasi yang memanggil commit()
di tengah rangkaian operasi. Tidak yakin apakah ini menjawab pertanyaan Anda.
Babak berikutnya adalah apa yang Anda sebutkan tentang threading. Jika aplikasi Anda multithread, sebaiknya pastikan yang Session
digunakan bersifat lokal untuk ... sesuatu. scoped_session()
secara default menjadikannya lokal untuk utas saat ini. Dalam aplikasi web, lokal ke permintaan bahkan lebih baik. Flask-SQLAlchemy sebenarnya mengirimkan "fungsi cakupan" kustom scoped_session()
sehingga Anda mendapatkan sesi yang mencakup permintaan. Rata-rata aplikasi Piramida memasukkan Sesi ke dalam registri "permintaan". Saat menggunakan skema seperti ini, ide "buat Sesi baru berdasarkan permintaan" terus terlihat seperti cara paling mudah untuk menjaga semuanya tetap lurus.