3

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

編集:

adodbapi の connect() メソッドまたはその cursor() メソッドのいずれかへの autocommit パラメータに類似するものはないようです。char および varchar データ型が 255 文字で切り捨てられることを除いて、adodbapi の代わりに pymssql を使用できれば幸いです。

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

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
4

4 に答える 4

2

「問題は、Python の DBAPI では、cursor.commit() によってのみコミットされるトランザクションにcursor.execute() をラップする必要があることです」

「そして、ユーザー トランザクションでデータベース ステートメントの削除または作成を実行することはできません。」

これが実際にすべての 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))')
于 2009-05-12T18:55:13.843 に答える
1

データベースがトランザクションをサポートしている場合、 adodbapi 接続オブジェクトconnは、コミットのたびに新しいトランザクションを自動的に開始します。DB-API では、自動コミットをデフォルトでオフにする必要があり、API メソッドでそれをオンに戻すことができますが、adodbapi には見当たりません。

conn.adoConnプロパティを使用して、DB-API の代わりに ADO API を使用してトランザクションから抜け出すことで、これを回避できる可能性があります。これがうまくいくかどうか教えてください:

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

adodbapi commit() メソッドのソースは次のとおりです。

于 2009-05-12T19:10:19.340 に答える
0

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

于 2009-05-12T18:28:29.020 に答える
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

于 2011-01-11T10:11:36.567 に答える