从Python创建SQL Server数据库

时间:2009-05-12 17:55:47

标签: python sql-server pywin32 adodbapi

我正在使用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

4 个答案:

答案 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时将无效。