Peewee:外部交易不会回滚内部交易(保存点)

时间:2016-08-29 03:19:30

标签: python transactions peewee

运行以下python脚本两次会抛出此错误:

peewee.ProgrammingError: relation "test_table" already exists

因为该表未在 .rollback()上删除。删除内部事务( with test_db.atomic())有效。为什么内部事务(根据documentation只是保存点)不会被回滚?

from datetime import datetime
from peewee import Model, DateTimeField
from playhouse.postgres_ext import PostgresqlExtDatabase

"""
CREATE ROLE test WITH LOGIN;
DROP DATABASE IF EXISTS test;
CREATE DATABASE test WITH OWNER test;
"""

CREDENTIALS = {
    "database": "test",
    "user": "test",
    "password": None,
    "host": "localhost",
    "port": 5432,
    "register_hstore": False,
}


test_db = PostgresqlExtDatabase(**CREDENTIALS)
test_db.connect()
test_db.set_autocommit(False)
test_db.begin()  # start transaction

class TestTable(Model):
    timestamp = DateTimeField(null=False, default=datetime(1970,1,1,0,0,0,))

    class Meta:
        db_table = "test_table"
        database = test_db

with test_db.atomic():

    TestTable.create_table()
    TestTable.create()

test_db.rollback()  # rollback transaction

print TestTable.get().timestamp
test_db.close()

版本

peewee==2.8.3
psycopg2==2.6.2

PostgreSQL 9.5.1 on x86_64-apple-darwin15.3.0, compiled by Apple LLVM version 7.0.2 (clang-700.1.81), 64-bit

1 个答案:

答案 0 :(得分:0)

根据您使用的数据库,DDL(架构更改)可能会或可能不会回滚。

Postgresql和SQLite似乎都支持回滚DDL,但MySQL不支持。

但是,SQLite的Python驱动程序有一个错误,导致它在您发出DDL时发出COMMIT。第一个补丁是在2010年提交的:http://bugs.python.org/issue10740

另请查看pysqlite2,它与标准库sqlite3基本相同:

https://github.com/ghaering/pysqlite/blob/ca5dc55b462a7e67072205bb1a9a0f62a7c6efc4/src/cursor.c#L537-L547