从Python创建SQL Server数据库
我正在用Python和pywin32的adodbapi写一个脚本,目的是创建一个SQL Server数据库,以及它所有相关的表、视图和存储过程。问题是,Python的DBAPI要求在执行cursor.execute()时必须放在一个事务中,而这个事务只能通过cursor.commit()来提交。而且,你不能在用户事务中执行删除或创建数据库的语句。有没有什么办法可以解决这个问题呢?
编辑:
在adodbapi的connect()方法或cursor()方法中,似乎没有类似于自动提交的参数。我很乐意使用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
4 个回答
在事务之外创建实际的数据库。我对Python不太熟悉,但应该有办法在数据库上执行用户提供的字符串,可以用这个字符串来执行创建数据库的命令。然后使用adodbapi来处理所有的表等等,最后提交这个事务。
问题在于,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))')
adodbapi的连接对象conn
在每次提交后会自动开始一个新的事务,前提是数据库支持事务。根据DB-API的规定,默认情况下需要关闭自动提交功能,并且允许通过API方法重新开启,但我在adodbapi中没有看到这样的选项。
你可以尝试使用conn.adoConn
这个属性,利用ADO API而不是DB-API来退出任何事务。试试看这个方法是否有效:
conn.adoConn.CommitTrans()
cursor.execute('CREATE DATABASE ...')
conn.adoConn.BeginTrans()
这里是adodbapi的commit()方法的源代码。