我正在使用Python和pywin32的adodbapi来编写脚本来创建SQL Server数据库及其所有相关的表,视图和过程。问题是Python的DBAPI要求cursor.execute()包装在仅由cursor.commit()提交的事务中,并且您不能在用户事务中执行drop或create database语句。关于如何解决这个问题的任何想法?
编辑:
对于adodbapi的connect()方法或其cursor()方法,似乎没有类似于autocommit参数的任何内容。我很乐意使用pymssql而不是adodbapi,除了它将char和varchar数据类型截断为255个字符。
我在发布前尝试过这个;这是追溯。
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
答案 0 :(得分:1)
“问题是Python的DBAPI要求cursor.execute()包含在一个只由cursor.commit()提交的事务中”
“并且您无法在用户事务中执行drop或create database语句。”
我不确定所有这些对所有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))')
答案 1 :(得分:1)
如果数据库支持事务,adodbapi连接对象conn
会在每次提交后自动启动新事务。 DB-API默认情况下需要关闭自动提交,它允许API方法重新打开它,但我没有在adodbapi中看到它。
您可以使用conn.adoConn
属性来解决此问题,使用ADO api而不是DB-API将您带出任何事务。如果有效,请告诉我:
conn.adoConn.CommitTrans()
cursor.execute('CREATE DATABASE ...')
conn.adoConn.BeginTrans()
以下是adodbapi commit() method的来源。
答案 2 :(得分:0)
在事务外创建实际的数据库。我不熟悉python,但必须有一种方法在数据库上执行用户给定的字符串,并将其与实际的create db命令一起使用。然后使用adodbapi执行所有表等,并提交该事务。
答案 3 :(得分: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
时将无效。