문제

PYWIN32의 ADODBAPI와 함께 Python을 사용하여 SQL Server 데이터베이스와 관련된 모든 테이블, 뷰 및 프로 시저를 작성하는 스크립트를 작성합니다. 문제는 Python의 DBAPI에서 Cursor.execute ()가 Cursor.commit ()에 의해서만 커밋 된 트랜잭션에 래핑해야하며 사용자 트랜잭션에서 드롭 또는 데이터베이스 문을 생성 할 수 없다는 것입니다. 그 점을 해결하는 방법에 대한 아이디어가 있습니까?

편집하다:

Autocommit 매개 변수와 Adodbapi의 Connect () 메소드와 유사한 것은없는 것 같습니다. 255 자로 Char 및 Varchar 데이터 유형을 자르고 있음을 제외하고는 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
도움이 되었습니까?

해결책

adodbapi 연결 객체 conn 데이터베이스가 트랜잭션을 지원하는 경우 모든 커밋 후 새 거래를 자동으로 시작합니다. DB-API는 기본적으로 AutoCommit을 꺼야하며 API 메소드를 다시 켜도록 허용하지만 Adodbapi에는 없습니다.

당신은 그것을 사용할 수 있습니다 conn.adoConn DB-API 대신 ADO API를 사용하여 거래에서 벗어나는 속성. 이것이 작동하는지 알려주세요 :

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

다음은 다음과 같습니다 adodbapi commit () 메소드.

다른 팁

"문제는 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))')

트랜잭션 외부에서 실제 DB를 만듭니다. Python에 익숙하지는 않지만 데이터베이스에서 사용자가 주어진 문자열을 실행하는 방법이 있어야합니다. 실제 DB 명령과 함께 사용하십시오. 그런 다음 adodbapi를 사용하여 모든 테이블 등을 수행하고 거래를 커밋하십시오.

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.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top