PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Masalah koneksi dengan SQLAlchemy dan beberapa proses

Mengutip "Bagaimana cara menggunakan mesin/koneksi/sesi dengan multiprosesor Python, atau os.fork()?" dengan penekanan tambahan:

Objek SQLAlchemy Engine mengacu pada kumpulan koneksi koneksi database yang ada. Jadi saat objek ini direplikasi ke proses anak, tujuannya adalah memastikan bahwa tidak ada koneksi database yang dibawa .

dan

Namun, untuk kasus Sesi atau Koneksi aktif-transaksi yang dibagikan, tidak ada perbaikan otomatis untuk ini; aplikasi perlu memastikan proses anak baru hanya memulai objek dan transaksi Koneksi baru, serta objek Sesi ORM.

Masalah ini berasal dari proses turunan bercabang yang mewarisi session global langsung , yang memegang Connection . Ketika target memanggil init , itu menimpa referensi global ke engine dan session , sehingga mengurangi penghitungan ulang mereka menjadi 0 pada anak, memaksa mereka untuk menyelesaikan. Jika Anda misalnya dengan satu atau lain cara membuat referensi lain ke sesi yang diwarisi pada anak, Anda mencegahnya dibersihkan – tetapi jangan lakukan itu. Setelah main telah bergabung dan kembali ke bisnis seperti biasa mencoba menggunakan koneksi yang sekarang berpotensi diselesaikan - atau tidak sinkron. Saya tidak yakin mengapa ini menyebabkan kesalahan hanya setelah sejumlah iterasi.

Satu-satunya cara untuk menangani situasi ini menggunakan global seperti yang Anda lakukan adalah dengan

  1. Tutup semua sesi
  2. Panggil engine.dispose()

sebelum garpu. Ini akan mencegah koneksi bocor ke anak. Misalnya:

def main():
    global session
    init()
    try:
        dummy = Dummy(value=1)
        session.add(dummy)
        session.commit()
        dummy_id = dummy.id
        # Return the Connection to the pool
        session.close()
        # Dispose of it!
        engine.dispose()
        # ...or call your cleanup() function, which does the same
        p = multiprocessing.Process(target=target, args=(dummy_id,))
        p.start()
        p.join()
        # Start a new session
        session = Session()
        dummy = session.query(Dummy).get(dummy_id)
        assert dummy.value == 2
    finally:
        cleanup()

Contoh kedua Anda tidak memicu finalisasi pada anak, dan sepertinya itu hanya berfungsi, meskipun mungkin rusak seperti yang pertama, karena masih mewarisi salinan sesi dan koneksi yang ditentukan secara lokal di main .




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bagaimana saya bisa mengimpor file .sql ke database postgres Heroku saya?

  2. 2 Cara Menambahkan Angka Nol di PostgreSQL

  3. Secara tidak sengaja menghapus hak pengguna super default postgres - dapatkah saya mendapatkannya kembali?

  4. Melakukan Perubahan Topologi Replikasi untuk PostgreSQL

  5. Webinar :Fitur Baru di PostgreSQL 11 [Tindak lanjut]