Peewee:外部事务不会回滚内部事务(保存点)
Peewee: Outer transaction does not roll back inner transaction (savepoints)
运行 以下 python 脚本两次抛出此错误:
peewee.ProgrammingError: relation "test_table" already exists
因为 table 没有在 .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
根据您使用的数据库,DDL(架构更改)可能无法回滚。
Postgresql 和 SQLite 似乎都支持回滚 DDL,但 MySQL 不支持。
但是,SQLite 的 Python 驱动程序有一个错误,导致它在您发出 DDL 时发出 COMMIT。第一个补丁于 2010 年提交:http://bugs.python.org/issue10740 .
另外看看 pysqlite2,它与标准库 sqlite3 基本相同:
运行 以下 python 脚本两次抛出此错误:
peewee.ProgrammingError: relation "test_table" already exists
因为 table 没有在 .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
根据您使用的数据库,DDL(架构更改)可能无法回滚。
Postgresql 和 SQLite 似乎都支持回滚 DDL,但 MySQL 不支持。
但是,SQLite 的 Python 驱动程序有一个错误,导致它在您发出 DDL 时发出 COMMIT。第一个补丁于 2010 年提交:http://bugs.python.org/issue10740 .
另外看看 pysqlite2,它与标准库 sqlite3 基本相同: