【问题标题】:Creating a SQL Server database from Python从 Python 创建 SQL Server 数据库
【发布时间】:2009-05-12 17:55:47
【问题描述】:

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

【问题讨论】:

    标签: python sql-server pywin32 adodbapi


    【解决方案1】:

    “问题在于 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))')
    

    【讨论】:

    • 你是对的 - all DBAPI 接口并非如此,但它是提供者允许的首选方法。我已经用与您的答案相关的更多信息更新了我的问题。感谢您的想法!
    【解决方案2】:

    如果数据库支持事务,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 的来源。

    【讨论】:

    • 差不多了。最终起作用的是: conn.adoConn.Execute("create database dummydatabase") 谢谢!我可能永远也想不通。
    【解决方案3】:

    在事务之外创建实际的数据库。我不熟悉python,但必须有一种方法可以在数据库上执行用户给定的字符串,并将其与实际的 create db 命令一起使用。然后使用 adodbapi 做所有的表等并提交该事务。

    【讨论】:

    • 是的,这是一个很好的问题重述。你知道如何做到这一点吗? Adodbapi 基本上没有文档记录,但我挖掘了它的单元测试,并且没有测试可以解决在事务之外运行 SQL 命令的问题。
    • 尝试使用 adodbapi 以外的方法来发出创建命令
    【解决方案4】:

    我在尝试通过 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 时什么都不做。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-14
      • 2012-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-16
      • 1970-01-01
      相关资源
      最近更新 更多