Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Mengapa manajer konteks Koneksi MySQLdb tidak menutup kursor?

Untuk menjawab pertanyaan Anda secara langsung:Saya tidak melihat ada salahnya menutup di akhir with memblokir. Saya tidak bisa mengatakan mengapa hal itu tidak dilakukan dalam kasus ini. Tetapi, karena ada kelangkaan aktivitas pada pertanyaan ini, saya telah menelusuri riwayat kode dan akan memberikan beberapa pemikiran (tebakan ) mengapa close() mungkin tidak dipanggil:

  1. Ada kemungkinan kecil bahwa memutar panggilan ke nextset() mungkin melemparkan pengecualian - mungkin ini telah diamati dan dilihat sebagai tidak diinginkan. Ini mungkin mengapa versi cursors.py berisi struktur ini di close() :

    def close(self):
        """Close the cursor. No further queries will be possible."""
        if not self.connection:
            return
    
        self._flush()
        try:
            while self.nextset():
                pass
        except:
            pass
        self.connection = None
    
  2. Ada potensi (agak jauh) bahwa mungkin perlu beberapa saat untuk memutar semua hasil yang tersisa tanpa melakukan apa-apa. Oleh karena itu close() mungkin tidak dipanggil untuk menghindari melakukan beberapa iterasi yang tidak perlu. Apakah Anda pikir itu layak untuk menyimpan siklus jam itu subjektif, saya kira, tetapi Anda bisa berdebat di sepanjang baris "jika tidak perlu, jangan lakukan".

  3. Menjelajahi komit sourceforge, fungsionalitas ditambahkan ke bagasi oleh komit ini pada tahun 2007 dan tampaknya bagian connections.py . ini tidak berubah sejak. Itu adalah gabungan berdasarkan komit ini , yang memiliki pesan

    Dan kode yang Anda kutip tidak pernah berubah sejak saat itu.

    Ini mendorong pemikiran terakhir saya - ini mungkin hanya upaya/prototipe pertama yang baru saja berhasil dan karenanya tidak pernah berubah.

Versi yang lebih modern

Anda menautkan ke sumber untuk konektor versi lama. Saya perhatikan ada garpu yang lebih aktif dari perpustakaan yang sama di sini , yang saya tautkan di komentar saya tentang "versi yang lebih baru" di poin 1.

Perhatikan bahwa versi yang lebih baru dari modul ini telah mengimplementasikan __enter__() dan __exit__() dalam cursor sendiri:lihat di sini . __exit__() di sini tidak panggil self.close() dan mungkin ini menyediakan cara yang lebih standar untuk menggunakan sintaks with mis.

with conn.cursor() as c:
    #Do your thing with the cursor

Catatan akhir

N.B. Saya kira saya harus menambahkan, sejauh yang saya mengerti pengumpulan sampah (bukan ahli juga) setelah tidak ada referensi ke conn , itu akan dialokasikan. Pada titik ini tidak akan ada referensi ke objek kursor dan itu akan dibatalkan alokasinya juga.

Namun memanggil cursor.close() tidak berarti bahwa itu akan menjadi sampah yang dikumpulkan. Itu hanya membakar melalui hasil dan mengatur koneksi ke None . Ini berarti tidak dapat digunakan kembali, tetapi tidak akan langsung menjadi sampah yang dikumpulkan. Anda dapat meyakinkan diri sendiri tentang hal itu dengan memanggil cursor.close() . secara manual setelah with blok dan kemudian, katakanlah, mencetak beberapa atribut cursor

N.B. 2 Saya pikir ini adalah penggunaan with yang agak tidak biasa sintaks sebagai conn objek tetap ada karena sudah berada di lingkup luar - tidak seperti, katakanlah, with open('filename') as f: di mana tidak ada objek yang berkeliaran dengan referensi setelah akhir with blokir.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Hapus dari beberapa tabel menggunakan order by dan limit

  2. Seperti apa internal dari pernyataan yang disiapkan?

  3. Bagaimana cara menerapkan sistem penandaan yang mirip dengan SO di php/mysql?

  4. Bagaimana menemukan delta waktu dari baris datatime di mysql?

  5. Kueri berparameter yang mengembalikan kolom TEXT selalu mengembalikan nol untuk kolom INT