Mysql
 sql >> база данни >  >> RDS >> Mysql

Защо контекстният мениджър на MySQLdb Connection не затваря курсора?

За да отговоря директно на въпроса ви:не виждам никаква вреда в затварянето в края на with блок. Не мога да кажа защо не е направено в този случай. Но тъй като има недостиг на активност по този въпрос, направих търсене в историята на кода и ще нахвърля няколко мисли (предположения ) защо close() може не се нарича:

  1. Има малък шанс за въртене чрез извиквания към nextset() може да хвърли изключение - вероятно това е било наблюдавано и възприето като нежелателно. Това може да е причината по-новата версия на cursors.py съдържа тази структура в 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. Има (донякъде отдалечен) потенциал, че може да отнеме известно време, за да превъртите всички останали резултати, без да правите нищо. Следователно close() може да не се извиква, за да се избегнат някои ненужни итерации. Предполагам, че смятате, че си струва да запазите тези часовникови цикли, е субективно, но можете да спорите в духа на „ако не е необходимо, не го правете“.

  3. Преглеждайки ангажиментите на sourceforge, функционалността беше добавена към ствола от този ангажимент през 2007 г. и изглежда, че този раздел на connections.py не се е променило оттогава. Това е сливане въз основа на този ангажимент , който съдържа съобщението

    И кодът, който цитирате, никога не е променян оттогава.

    Това подтиква последната ми мисъл - вероятно е само първи опит/прототип, който току-що е проработил и следователно никога не е променян.

По-модерна версия

Свързвате към източника за наследена версия на конектора. Отбелязвам, че има по-активно разклонение на същата библиотека тук , към който давам връзка в коментарите си за „по-нова версия“ в точка 1.

Обърнете внимание, че по-новата версия на този модул е ​​имплементирала __enter__() и __exit__() в cursor себе си:вижте тук . __exit__() тук прави извикване на self.close() и може би това осигурява по-стандартен начин за използване на синтаксиса with, напр.

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

Крайни бележки

N.B. Предполагам, че трябва да добавя, доколкото разбирам събирането на отпадъци (също не съм експерт), след като няма препратки към conn , то ще бъде отменено. В този момент няма да има препратки към обекта на курсора и той също ще бъде освободен.

Въпреки това извикване на cursor.close() не означава, че ще се събира боклук. Той просто записва резултатите и настройва връзката на None . Това означава, че не може да се използва повторно, но няма да бъде изхвърлен веднага на боклука. Можете да се убедите в това, като извикате ръчно cursor.close() след вашия with блок и след това, да речем, отпечатване на някакъв атрибут на cursor

N.B. 2 Мисля, че това е малко необичайно използване на with синтаксис като conn обектът продължава, защото вече е във външния обхват - за разлика, да речем, от по-често срещания with open('filename') as f: където няма обекти, висящи наоколо с препратки след края на with блокирай.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Съкращаване на данни:Неправилна стойност за дата и час:''

  2. MySQL динамичен напречен раздел

  3. Изберете MySQL база данни на Linux чрез командния ред

  4. Как да конвертирате тип колона varchar в тип дата, без да губите датите

  5. MySQL плътен ранг за всяка група/раздел