2

確立されたデータベースのデータにアクセスするスクリプトを書いていますが、残念ながら DB を壊しています。コマンドラインから問題を再現できます:

    [user@box tmp]# パイソン
    Python 2.7.2 (デフォルト、2011 年 9 月 19 日 15:02:41)
    [GCC 4.1.2 20080704 (Red Hat 4.1.2-48)] linux2 上
    詳細については、「ヘルプ」、「著作権」、「クレジット」、または「ライセンス」と入力してください。
    >>> 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 in transaction」と表示します。db.close() を呼び出すとすべて問題ありませんが、スクリプトが無限にループし、ループごとに db 接続を開いたり閉じたりする必要があるとは思いませんでした。上記のデータを使用していないという事実とは何の関係もないと思います。実際のスクリプトでは、(ループで) fetchone() を呼び出してデータを処理しています。私はあまり DB に詳しくないので、他にどのような情報が役立つかわかりません。上記のように、私のpostgresバージョンは9.1.0で、pythonは2.7.2です。

4

2 に答える 2

2

db.rollback()カーソルを閉じる前に(または書き込み操作を行っている場合は)呼び出してみてくださいdb.commit()

于 2011-10-06T01:22:58.827 に答える
2

pgdb の代わりに psycopg2 を使用することをお勧めします。pgdb は次のセマンティクスを使用します。

connect() -> データベース接続のオープン、トランザクションの開始
commit() -> コミット、トランザクションの開始
rollback() -> ロールバック、トランザクションの開始
execute() -> ステートメント の実行

一方、psycopg2 は次のセマンティクスを使用します。

connect() -> データベース接続を開く
commit() -> コミット
rollback() -> ロールバック
execute() -> まだトランザクションにない限りトランザクションを開始し、ステートメントを実行する

そのため、Amber が述べたように、select ステートメントの後にロールバックまたはコミットを実行して、トランザクションを終了できます。残念ながら、pgdb を使用すると、ロールバックまたはコミット後 (何も作業を実行していなくても) すぐに新しいトランザクションを開始します。

多くのデータベース システムでは、pgdb の動作は問題ありませんが、PostgreSQL がトランザクションを処理する方法が原因で、同じテーブルにアクセスする接続が多数ある場合に問題が発生する可能性があります (特にバキュームでの問題)。

なぜpgdbはすぐにトランザクションを開始するのですか? Python DB-API (2.0) 仕様では、そうすることが求められています。私にはばかげているように思えますが、それが仕様の書き方です。

于 2011-10-06T04:34:31.477 に答える