Создание базы данных SQL Server из Python - PullRequest
3 голосов
/ 12 мая 2009

Я использую Python с adodbapi pywin32 для написания скрипта для создания базы данных SQL Server и всех связанных с ней таблиц, представлений и процедур. Проблема в том, что DBAPI Python требует, чтобы cursor.execute () был заключен в транзакцию, которая фиксируется только курсором cursor (), и вы не можете выполнить удаление или создать оператор базы данных в пользовательской транзакции. Любые идеи о том, как обойти это?

EDIT:

Кажется, нет ничего похожего на параметр autocommit ни для метода connect () adodbapi, ни для его метода 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 ]

2 голосов
/ 12 мая 2009

"Проблема в том, что DBAPI Python требует, чтобы cursor.execute () был заключен в транзакцию, которая фиксируется только курсором cursormit ()"

"и вы не можете выполнить удаление или создать оператор базы данных в пользовательской транзакции."

Я не уверен, что все это действительно верно для всех интерфейсов 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 голос
/ 12 мая 2009

Объект подключения adodbapi conn автоматически запускает новую транзакцию после каждой фиксации, если база данных поддерживает транзакции. DB-API требует, чтобы автокоммит был выключен по умолчанию, и он позволяет методу API включить его, но я не вижу его в adodbapi.

Возможно, вы сможете использовать свойство conn.adoConn для обхода этого, используя API ADO вместо DB-API, чтобы вывести вас из любой транзакции. Дайте мне знать, если это работает:

conn.adoConn.CommitTrans()
cursor.execute('CREATE DATABASE ...')
conn.adoConn.BeginTrans()

Вот исходный код метода adodbapi commit () .

0 голосов
/ 11 января 2011

У меня была такая же проблема при попытке запуска команд через 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.

0 голосов
/ 12 мая 2009

создать фактический дБ вне транзакции. Я не знаком с python, но должен быть способ выполнить заданную пользователем строку в базе данных, использовать ее с фактической командой create db. Затем используйте adodbapi для создания всех таблиц и т. Д. И зафиксируйте эту транзакцию.

...