2016-07-14 14 views
1

Ich möchte mehrere komplexe Anweisungen in einer Transaktion mit einer Select-Anweisung am Ende ausführen, die ich für die weitere Verarbeitung verwenden.Wie erstellt man mehrere komplexe sqlite-Transaktionen mit einer erwarteten Verwendung von apsw?

Dies funktioniert einmal gut, aber sobald ich dieselbe Anweisung erneut ausführen, verursacht es den Fehler unten.

Prüfregeln:

import apsw 
connection = apsw.Connection("temp.db") 

cursor = connection.cursor() 
cursor.execute(""" 
BEGIN TRANSACTION; 
CREATE TABLE Foo(x); 
COMMIT; 
""") 

cursor = connection.cursor() 
print(cursor.execute(""" 
BEGIN TRANSACTION; 
INSERT INTO Foo (x) VALUES (1); 
INSERT INTO Foo (x) VALUES (2); 
SELECT x FROM Foo LIMIT 1; 
COMMIT; 
""").fetchone()) 


cursor = connection.cursor() 
print(cursor.execute(""" 
BEGIN TRANSACTION; 
INSERT INTO Foo (x) VALUES (3); 
INSERT INTO Foo (x) VALUES (4); 
SELECT x FROM Foo LIMIT 1; 
COMMIT; 
""").fetchone()) 

Ausgang:

$ python test.py 
(1,) 
Traceback (most recent call last): 
    File "test.py", line 28, in <module> 
    """).fetchone()) 
    File "src/cursor.c", line 236, in resetcursor 
apsw.SQLError: SQLError: cannot start a transaction within a transaction 

Edit: Es scheint der "fetchone()" Methode angeschlossen werden, wenn ich statt "fetchall()" verwenden, es funktioniert . In meinem speziellen Fall erwarte ich von einem Ergebnis, also habe ich den Code entsprechend bearbeitet.

+0

Mögliche Duplikate von [Python sqlite "BEGIN TRANSACTION" und "COMMIT" -Befehle] (http://Stackoverflow.com/questions/26770719/python-sqlite-begin-transaction-and-commit-commands) – AndrewK

Antwort

0

SQLite berechnet Ergebnisse im laufenden Betrieb. Wenn Sie fetchone() aufrufen, wird die Ausführung nur so weit wie erforderlich ausgeführt, um eine Zeile zurückzugeben.

Um sicherzustellen, dass alle Anweisungen ausgeführt werden, rufen Sie fetchall(), oder durchlaufen Sie die Ergebnisse, auch wenn Sie wissen, dass es nur eine gibt.

Es könnte eine bessere Idee sein, nicht so viele Anweisungen wie möglich in eine einzige SQL-Zeichenfolge zu komprimieren.

+0

Vielen Dank für die hilfreiche Antwort, ich denke, ich werde 'fetchall()' verwenden müssen, da ich alle Anweisungen in eine Transaktion komprimieren muss, um den korrekten Zustand sicherzustellen. –

+0

Sie müssen kein einziges 'execute' für eine einzelne Transaktion verwenden. –