2016-08-29 7 views
1

Идущих следующий питон скрипт дважды выдает эту ошибку:Peewee: Внешняя транзакция не выполняет отката внутренней транзакции (точки сохранения)

peewee.ProgrammingError: relation "test_table" already exists 

, потому что таблица не удаляется на .rollback(). Удаление внутренней транзакции (с 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 
+0

Я играл с этим немного больше, и даже если я добавить второй тестовой таблицы ** внутри ** внешняя транзакция, но ** вне ** _test_db.atomic() _ она не удаляется при * откате *. Обе таблицы удаляются без инструкции * test_db.atomic() *. – kev

ответ

0

В зависимости от базы данных, которую вы используете, DDL (изменения схемы) может или не может быть возможно откатить.

Postgresql и SQLite оба поддерживают откатывание DDL, но MySQL этого не делает.

Однако драйвер Python для SQLite имеет ошибку, которая заставляет ее выдавать COMMIT при выдаче DDL. Первый патч был представлен в 2010 году: http://bugs.python.org/issue10740.

Также обратите внимание на pysqlite2, который по существу такой же, как стандартная библиотека sqlite3:

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

+0

Я использую Postgres (PostgresqlExtDatabase). – kev