2009-05-12 27 views
3

pywin32のadodbapiでPythonを使用して、SQL Serverデータベースと関連するすべてのテーブル、ビュー、およびプロシージャを作成するスクリプトを作成しています。問題は、PythonのDBAPIでは、cursor.execute()がcursor.commit()によってコミットされたトランザクションにラップされ、ユーザートランザクションでdropまたはcreate database文を実行できないことです。それを回避する方法に関するアイデア?PythonからSQL Serverデータベースを作成する

EDIT:

接続adodbapiの()メソッドまたはそのカーソル()メソッドのいずれかに自動コミット・パラメータに類似したものがあるように思えません。私はadodbapiの代わりにpymssqlを使用していますが、255文字のcharおよびvarcharデータ型を切り捨てる点が異なります。

投稿する前にこれを試しました。ここにトレースバックです。

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 

答えて

1

adodbapi接続オブジェクトconnは、自動的に新しいトランザクションを開始しません。 DB-APIでは、自動コミットがデフォルトでオフになっている必要があり、APIメソッドでAPIを有効にすることができますが、adodbapiでは表示されません。

conn.adoConnプロパティを使用して、DB-APIの代わりにADO APIを使用して、このトランザクションをハックすることができます。これが動作するかどうか、私に教えてください:ここで

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

adodbapi commit() methodのソースです。

+1

それは近いです。最後に働いたのは次のとおりです。 conn.adoConn.Execute( "データベース作成用データベース") ありがとう!私は決してそれを理解できなかったかもしれません。 – JasonFruit

0

実際のデータベースをトランザクション外に作成します。私はPythonに慣れていませんが、実際にdbコマンドを作成して使用すると、データベース上で指定された文字列を実行する方法が必要です。次に、adodbapiを使用してすべてのテーブルなどを実行し、そのトランザクションをコミットします。

+0

はい、それは質問の良い再記述です。あなたはそれをどのように達成するか考えていますか? Adodbapiは主に文書化されていませんが、私は単体テストを掘り下げましたが、トランザクション外でSQLコマンドを実行するテストはありません。 – JasonFruit

+0

adodbapi以外のものを試してみてください。 –

1

「「問題は、PythonのDBAPIはcursor.executeは()のみcursor.commit()によってコミットされたトランザクションに包まれることを必要とすることである」と、あなたは、ドロップを実行したり、データベースを作成することはできません。ユーザートランザクションのステートメント。

これは、すべてのDBAPIインターフェイスで実際に当てはまるとは限りません。

エラーメッセージが表示されないため、ADODBAPIインターフェイスではこれが当てはまらないことがあります。実際に試しましたか?もしそうなら、どんなエラーメッセージが表示されますか?

接続がありません常に "ユーザートランザクション"を作成している可能性があります。 autocommit=Trueで接続を開いて、DDLスタイルの自動コミットを取得することができます。

また、DDLを実行するために別の接続を使用することも考えてください。

http://pymssql.sourceforge.net/たとえば、このようにDDLが実行されていることを示します。データベースがトランザクションをサポートしている場合、すべてのコミット後

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))') 
+0

あなたは正しいのですが、それは*すべての* DBAPIインターフェイスには当てはまりませんが、プロバイダーが許可したときの好ましい方法です。私はあなたの答えに関連するより多くの情報で私の質問を更新しました。アイデアありがとう! – JasonFruit

0

adodbapi(例:DBCC CHECKDB ...)でコマンドを実行しようとしているときに同じ問題が発生し、joeforkerのアドバイスが少し助けになりました。私がまだ持っていた問題は、adodbapiが自動的にトランザクションを開始するため、トランザクション外で何かを実行する方法がないことでした。私はadodbapi年代を無効にしてしまった最後に

は次のように行動をコミット:

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 

は、私の知る限り、この標準のSQL Serverが機能を自動コミット再可能となり、各SQLステートメントが自動的に、すなわちコミット。欠点は、Connection.commit()supportsTransactions == Falseのときに何もしないので、トランザクション内で何かを実行したくない場合に、トランザクションを再び有効にする方法がないことです(現時点で)。

関連する問題