свисающая база данных python pgdb - PullRequest
2 голосов
/ 06 октября 2011

Я пишу скрипт для доступа к данным в установленной базе данных, и, к сожалению, я ломаю БД.Я могу воссоздать проблему из командной строки:

    [user@box tmp]# python
    Python 2.7.2 (default, Sep 19 2011, 15:02:41) 
    [GCC 4.1.2 20080704 (Red Hat 4.1.2-48)] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import pgdb
    >>> db = pgdb.connect('localhost:my_db:postgres')
    >>> cur = db.cursor()
    >>> cur.execute("SELECT * FROM mytable LIMIT 10")
    >>> cur.close()
    >>> 

На этом этапе любая активность mytable значительно ухудшается, и «select * from pg_stat_activity» показывает мое соединение как «IDLE в транзакции».Если я вызываю db.close (), все в порядке, но мой сценарий зацикливается бесконечно, и я не думаю, что мне нужно открывать и закрывать соединение db с каждым циклом.Я не думаю, что это имеет какое-либо отношение к тому факту, что я не использую данные выше, так как в моем реальном скрипте я вызываю fetchone () (в цикле) для обработки данных.Я не большой парень в БД, поэтому я не уверен, какая другая информация будет полезна.Моя версия postgres - 9.1.0, а python - 2.7.2, как показано выше.

Ответы [ 2 ]

2 голосов
/ 06 октября 2011

Я предлагаю использовать psycopg2 вместо pgdb.pgdb использует следующую семантику:

connect () -> открыть соединение с базой данных, начать транзакцию
commit () -> commit, начать транзакцию
rollback () -> откат, начать транзакцию
execute () -> оператор execute

psycopg2, с другой стороны, использует следующую семантику:

connect () -> открытое соединение с базой данных
commit () -> commit
rollback () -> rollback
execute () -> начать транзакцию, если она уже не в транзакции, выполнить оператор

, поэтому, как упоминала Эмбер, вы можете выполнить откат или фиксацию после оператора select и завершить операциюсделка.К сожалению, с pgdb вы сразу же начнете новую транзакцию после отката или фиксации (даже если вы не выполняли никакой работы).

Для многих систем баз данных поведение pgdb хорошо, но из-за способаPostgreSQL обрабатывает транзакции, это может создать вам проблемы, если у вас много соединений, обращающихся к одним и тем же таблицам (проблемы, в частности, с вакуумом).

Почему pgdb запускает транзакцию сразу?Спецификация Python DB-API (2.0) требует для этого.Мне это кажется глупым, но так написана спецификация.

2 голосов
/ 06 октября 2011

Попробуйте вызвать db.rollback() перед тем, как закрыть курсор (или, если вы выполняете операцию записи, db.commit()).

...