sql >> Databasteknik >  >> RDS >> Mysql

Varför stänger inte MySQLdb Connection-kontexthanteraren markören?

För att svara direkt på din fråga:Jag kan inte se någon som helst skada i att avsluta i slutet av en with blockera. Jag kan inte säga varför det inte görs i det här fallet. Men eftersom det finns en brist på aktivitet på den här frågan, sökte jag igenom kodhistoriken och kommer att lägga in några tankar (gissningar ) om varför close() kan inte kallas:

  1. Det finns en liten chans att snurra igenom anrop till nextset() kan göra ett undantag - möjligen hade detta observerats och setts som oönskat. Det kan vara anledningen till att den nyare version av cursors.py innehåller denna struktur i 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. Det finns den (något avlägsna) potentialen att det kan ta lite tid att snurra igenom alla återstående resultat utan att göra någonting. Därför close() kanske inte kallas för att undvika att göra några onödiga iterationer. Om du tycker att det är värt att spara dessa klockcykler är subjektivt, antar jag, men du kan argumentera i stil med "om det inte är nödvändigt, gör det inte".

  3. När du bläddrar i sourceforge-commits lades funktionen till i trunk av thise /a> 2007 och det verkar som om det här avsnittet av connections.py har inte förändrats sedan dess. Det är en sammanslagning baserad på detta åtagande , som har meddelandet

    Och koden du citerar har aldrig ändrats sedan dess.

    Detta får min sista tanke - det är förmodligen bara ett första försök/prototyp som bara fungerade och därför aldrig ändrades.

Modernare version

Du länkar till källan för en äldre version av anslutaren. Jag noterar att det finns en mer aktiv gaffel av samma bibliotek här , som jag länkar till i mina kommentarer om "nyare version" i punkt 1.

Observera att den nyare versionen av denna modul har implementerat __enter__() och __exit__() inom cursor sig själv:se här . __exit__() här gör ring self.close() och kanske ger detta ett mer standardiserat sätt att använda med syntax, t.ex.

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

Slutanteckningar

Obs. Jag antar att jag borde lägga till, så vitt jag förstår sophämtning (inte en expert heller) när det inte finns några referenser till conn , kommer den att omallokeras. Vid denna tidpunkt kommer det inte att finnas några referenser till markörobjektet och det kommer också att avallokeras.

Men anropar cursor.close() betyder inte att det kommer att samlas in. Den bränner helt enkelt igenom resultaten och ställer in anslutningen till None . Det betyder att det inte kan återanvändas, men det kommer inte att samlas in omedelbart. Du kan övertyga dig själv om det genom att manuellt anropa cursor.close() efter din with blockera och sedan, säg, skriva ut något attribut för cursor

OBS. 2 Jag tror att detta är en något ovanlig användning av with syntax som conn objekt kvarstår eftersom det redan är i det yttre omfånget - till skillnad från t.ex. det vanligare with open('filename') as f: där det inte finns några objekt som hänger runt med referenser efter slutet av with blockera.




  1. Hur får man fram primärnyckeln för senast uppdaterade post i MYSQL?

  2. mysql aggregat UDF (användardefinierad funktion) i C

  3. IIS 7.5 använder 32-bitars drivrutin istället för 64-bitars

  4. PHP - MYSQL Okänt kolumn i WHERE Join