Судя по той же документации, правильный шаблон использования будет примерно такой:
conn = psycopg2.connect(DSN)try: with conn: with conn.cursor() as curs: curs.execute(SQL1) with conn: with conn.cursor() as curs: curs.execute(SQL2)finally: conn.close()
Что тут имеется в виду.
connection живёт столько, сколько нужно вам для ваших операций, если у вас операции с базой идут подряд - connection не надо закрывать и переоткрывать; но если вы поработали с базой, а потом у вас перерыв - вы, например, перемалываете какие-то данные и пока базу не пишете и не читаете, то connection лучше закрыть, чтобы она ушла в пул и другим процессам, работающим с базой, хватило этих самых connection; и да - connection лучше закрывать в конце работы с ней и делать это наверняка (через try/finally), чтобы точно освободить связанные с ней ресурсыtransaction лучше создавать и закрывать с помощью блока with conn: - если не будет брошено исключение в течении работы блока with, то будет автоматически сделан commit, а если будет исключение - будет выполнен rollback; в одном блоке транзакции нужно объединять некий неразрывный блок работы с базой, который должен быть откачен целиком в случае неудачи, а в случае успешного завершения запись данных этого блока опять же должна представлять из себя в базе фрагмент данных, который ничего не поломает, будучи записанным в базу сам по себеcursor - похоже, в приведённом мной шаблоне использования это просто объект, который позволяет выполнять любые операции записи/чтения внутри одной транзакции и он сам закроется по окончании блока with conn.cursor() as curs:
Немного странно, что в приведённом вами примере без with курсор получается закрывается уже после commit, видимо, можно делать и так и так. Если курсор не закрывать самому, то он, видимо, остаётся открытым всё время существования connection. Но опять же, согласно документации, лучше курсор обязательно закрыть (и удобнее сделать это неявно с помощью блока with), чтобы он точно освободил какие-то ресурсы, которые на него выделены. Хотя, наверняка, закрытие connection и так освободит все ресурсы.
В общем, мне кажется, тут есть довольно большая свобода выбора шаблона, однако, блоки with позволяют более чётко разделить этапы работы программы с базой, если таковые этапы имеют место быть.
P.S. Конкретно по вашим вопросам отдельно:
Я напихал в БД 20000 записей при помощи 100 батчей. Нужно ли мне создавать новое соединение?
Если вы работаете с базой непрерывно, то новое соединение создавать не нужно.
А курсор? При этом, я считаю, что у меня будут ещё записи.
Опять же - это зависит от того, планируете ли вы держать и дальше открытым соединение, можно ли вашу работу записывать в базу по частям, и какой шаблон работы с базой вы выберете. При непрерывной работе с базой похоже можно открыть соединение и курсор один раз, а потом, при необходимости, делать коммиты после каждого куска выполненной работы (если она в вашем случае может быть записана в базу этими кусками и ничего при этом не поломается).
P.P.S. Отвечая на тему вопроса - в той же документации написано, что если не включен autocommit mode, при котором connection сам делает commit после каждой операции с курсором, то если не сделать после операций с курсором явный commit и при этом закрыть connection, то можно остаться в результате с грязными данными - состояние ваших данных в базе будет неопределённое (но это сильно зависит от конкретной базы данных), в худшем случае транзакция может вообще подвиснуть и залочить дальнейшие операции с базой до принудительной перезагрузки сервера БД. Нормальная БД в случае потери коннекшена, конечно, сделает rollback, но лучше до такого в любом случае не доводить.