Frage

Ich verwende Python mit pywin32 des adodbapi ein Skript zu schreiben, um eine SQL Server-Datenbank zu erstellen und alle zugehörigen Tabellen, Views und Prozeduren. Das Problem ist, dass Python DBAPI erfordert, dass cursor.execute () in einer Transaktion eingewickelt werden, die nur durch cursor.commit begangen wird (), und Sie können keinen Tropfen oder erstellen Datenbank-Anweisung in einer Benutzertransaktion auszuführen. Alle Ideen, wie um das zu bekommen?

EDIT:

Es scheint nicht zu etwas analog zu einem autocommit Parameter entweder die connect () -Methode von adodbapi oder dessen Cursor () -Methode. Ich würde gerne pymssql verwenden, anstatt adodbapi, mit der Ausnahme, dass es char und varchar-Datentypen auf 255 Zeichen abschneidet.

habe ich versuchen, dies vor der Veröffentlichung; hier ist die Rückverfolgung.

Traceback (most recent call last):
  File "demo.py", line 39, in <module>
    cur.execute("create database dummydatabase")
  File "C:\Python26\lib\site-packages\adodbapi\adodbapi.py", line 713, in execute
    self._executeHelper(operation,False,parameters)
  File "C:\Python26\lib\site-packages\adodbapi\adodbapi.py", line 664, in _executeHelper
    self._raiseCursorError(DatabaseError,tracebackhistory)
  File "C:\Python26\lib\site-packages\adodbapi\adodbapi.py", line 474, in _raiseCursorError
    eh(self.conn,self,errorclass,errorvalue)
  File "C:\Python26\lib\site-packages\adodbapi\adodbapi.py", line 60, in standardErrorHandler
    raise errorclass(errorvalue)
adodbapi.adodbapi.DatabaseError: 
--ADODBAPI
Traceback (most recent call last):
   File "C:\Python26\lib\site-packages\adodbapi\adodbapi.py", line 650, in _executeHelper
    adoRetVal=self.cmd.Execute()
   File "<COMObject ADODB.Command>", line 3, in Execute
   File "C:\Python26\lib\site-packages\win32com\client\dynamic.py", line 258, in _ApplyTypes_
    result = self._oleobj_.InvokeTypes(*(dispid, LCID, wFlags, retType, argTypes) + args)
 com_error: (-2147352567, 'Exception occurred.', (0, u'Microsoft SQL Native Client', u'CREATE DATABASE statement not allowed within multi-statement transaction.', None, 0, -2147217900), None)
-- on command: "create database dummydatabase"
-- with parameters: None
War es hilfreich?

Lösung

Das adodbapi Verbindungsobjekt conn startet automatisch eine neue Transaktion nach jedem Commit, wenn die Datenbank Transaktionen unterstützt. DB-API autocommit erfordert standardmäßig deaktiviert werden und ermöglicht eine API-Methode, um es wieder einzuschalten, aber ich sehe nicht ein in adodbapi.

könnten Sie in der Lage sein, die conn.adoConn Eigenschaft zu verwenden, um dies zu hacken, die ADO api statt DB-API verwenden Sie aus jeder Transaktion zu übernehmen. Lassen Sie mich wissen, ob das funktioniert:

conn.adoConn.CommitTrans()
cursor.execute('CREATE DATABASE ...')
conn.adoConn.BeginTrans()

Hier ist die Quelle für die adodbapi commit () -Methode .

Andere Tipps

"Das Problem ist, dass Python DBAPI erfordert, dass cursor.execute () in einer Transaktion eingewickelt werden, die nur durch cursor.commit () begangen wird"

„und Sie können keinen Tropfen ausführen oder Datenbank-Anweisung in einer Benutzertransaktion erstellen.“

Ich bin nicht sicher, ob all dies für alle DBAPI Schnittstellen tatsächlich wahr ist.

Da Sie nicht die Fehlermeldungen zeigen, kann es sich herausstellen, dass dies für ADODBAPI Schnittstelle ist nicht wahr. Haben Sie es wirklich versucht? Wenn ja, welche Fehlermeldung erhalten Sie?

Eine Verbindung kann nicht immer eine "Benutzertransaktion" erschaffen. Sie können oft offene Verbindungen mit autocommit=True DDL-Stil autocommit zu erhalten.

Auch möchten Sie vielleicht eine andere Verbindung zu prüfen, unter Verwendung einer Lauf DDL zu tun.

http://pymssql.sourceforge.net/ zeigt zum Beispiel DDL wie diese ausgeführt wird.

import pymssql
conn = pymssql.connect(host='SQL01', user='user', password='password', database='mydatabase')
cur = conn.cursor()
cur.execute('CREATE TABLE persons(id INT, name VARCHAR(100))')

die tatsächliche db außerhalb der Transaktion erstellen. Ich bin nicht vertraut mit Python, aber es muss ein Weg sein, um einen Benutzer angegebene Zeichenfolge auf einer Datenbank ausführen, verwenden Sie das mit der db Befehl tatsächlich erstellen. Dann die adodbapi verwenden, um alle Tabellen zu tun, etc. und diese Transaktion verpflichten.

Ich hatte das gleiche Problem, während Ausführen von Befehlen über adodbapi versuchen (z DBCC CHECKDB ...) und Rat des joeforker ein wenig geholfen. Das Problem, das ich noch hatte, dass adodbapi startet automatisch eine Transaktion, so dass es keine Möglichkeit, etwas außerhalb einer Transaktion auszuführen.

Am Ende landete ich deaktivieren adodbapi Verhalten wie diese begehen:

self.conn = adodbapi.connect(conn_str)
# rollback the transaction that was started in Connection.__init__()
self.conn.adoConn.RollbackTrans() 
# prevent adodbapi from trying to rollback a transaction in Connection.close()
self.conn.supportsTransactions = False

Soweit ich sagen kann, diese wieder aktiviert die Standard-SQL Server autocommit Funktionalität, das heißt jede SQL-Anweisung automatisch festgelegt wird. Der Nachteil ist, dass es für mich keine Möglichkeit, wieder zu aktivieren, damit Transaktionen (im Moment), wenn ich etwas innerhalb einer Transaktion ausführen wan't, da Connection.commit() nichts tun wird, wenn supportsTransactions == False.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top