sql >> Database teknologi >  >> RDS >> Mysql

Hvorfor lukker MySQLdb Connection-kontekstmanageren ikke markøren?

For at besvare dit spørgsmål direkte:Jeg kan ikke se nogen som helst skade i at lukke i slutningen af ​​en with blok. Jeg kan ikke sige, hvorfor det ikke er gjort i dette tilfælde. Men da der er mangel på aktivitet på dette spørgsmål, søgte jeg gennem kodehistorikken og vil kaste et par tanker ind (gæt ) om hvorfor close() kan ikke kaldes:

  1. Der er en lille chance for, at det drejer sig om opkald til nextset() kan give en undtagelse - muligvis var dette blevet observeret og set som uønsket. Det kan være grunden til, at den nyere version af cursors.py indeholder denne 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. Der er det (noget fjerntliggende) potentiale, at det kan tage noget tid at snurre gennem alle de resterende resultater uden at gøre noget. Derfor close() kaldes muligvis ikke for at undgå at lave nogle unødvendige gentagelser. Jeg formoder, at det er subjektivt, om du synes, det er værd at gemme disse urcyklusser, men du kan argumentere i retning af "hvis det ikke er nødvendigt, så lad være med at gøre det".

  3. Når du gennemser sourceforge-commits, blev funktionaliteten tilføjet til trunk af denne forpligtelse , som har meddelelsen

    Og den kode, du citerer, har aldrig ændret sig siden.

    Dette giver anledning til min sidste tanke - det er nok bare et første forsøg / prototype, der bare virkede og derfor aldrig blev ændret.

Mere moderne version

Du linker til kilden for en ældre version af forbindelsen. Jeg bemærker, at der er en mere aktiv forgrening af det samme bibliotek her , som jeg linker til i mine kommentarer om "nyere version" i punkt 1.

Bemærk, at den nyere version af dette modul har implementeret __enter__() og __exit__() inden for cursor sig selv:se her . __exit__() her gør ring self.close() og måske giver dette en mere standard måde at bruge syntaksen på, f.eks.

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

Slutnoter

N.B. Jeg tror, ​​jeg skal tilføje, så vidt jeg forstår affaldsindsamling (heller ikke en ekspert), når der ikke er nogen referencer til conn , vil den blive omfordelt. På dette tidspunkt vil der ikke være nogen referencer til markørobjektet, og det vil også blive deallokeret.

Men kalder cursor.close() betyder ikke, at det bliver indsamlet affald. Den brænder simpelthen resultaterne igennem og indstiller forbindelsen til None . Det betyder, at det ikke kan genbruges, men at det ikke bliver samlet op med det samme. Du kan overbevise dig selv om det ved manuelt at kalde cursor.close() efter din with blok og derefter f.eks. udskrive en eller anden attribut for cursor

N.B. 2 Jeg tror, ​​at dette er en noget usædvanlig brug af with syntaks som conn objektet består, fordi det allerede er i det ydre omfang - i modsætning til f.eks. den mere almindelige with open('filename') as f: hvor der ikke er nogen objekter, der hænger rundt med referencer efter slutningen af ​​with blokere.




  1. SQL Azure:Database XXXYYY på serveren er ikke tilgængelig i øjeblikket

  2. MYSQL 8 timers timeout-problem

  3. Bedste mysql-datatype for gram, milligram, mikrogram og kilojoule

  4. Fundamentals of Table Expressions, Del 12 – Inline Table-Valued Functions