从Python创建SQL Server数据库

3 投票
4 回答
11364 浏览
提问于 2025-04-15 11:33

我正在用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 个回答

0

在事务之外创建实际的数据库。我对Python不太熟悉,但应该有办法在数据库上执行用户提供的字符串,可以用这个字符串来执行创建数据库的命令。然后使用adodbapi来处理所有的表等等,最后提交这个事务。

2

问题在于,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))')
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()方法的源代码。

撰写回答