سؤال

وأنا باستخدام بايثون مع adodbapi pywin32 لكتابة السيناريو لإنشاء قاعدة بيانات خادم SQL وبكل ما فيها من الجداول المرتبطة، وجهات النظر، والإجراءات. والمشكلة هي أن DBAPI بيثون يتطلب أن cursor.execute () أن تكون ملفوفة في المعاملات التي تلتزم فقط من قبل cursor.commit ()، وأنت لا يمكن تنفيذ قطرة أو إنشاء قاعدة بيانات بيان في معاملة مستخدم. أي أفكار عن كيفية الحصول على حول ذلك؟

وتحرير:

وهناك لا يبدو أن يكون أي شيء مماثل لمعلمة AUTOCOMMIT إما إلى طريقة ربط () من adodbapi أو منهجه المؤشر (). سأكون سعيدا لاستخدام pymssql بدلا من adodbapi، إلا أنه يقتص شار وVARCHAR أنواع البيانات في 255 حرفا.

ولم أحاول هذا قبل النشر. وهنا traceback.

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
هل كانت مفيدة؟

المحلول

ووadodbapi كائن اتصال conn لا تبدأ تلقائيا معاملة جديدة بعد كل ارتكاب إذا كانت قاعدة البيانات تدعم المعاملات. DB-API يتطلب AUTOCOMMIT يمكن إيقاف افتراضيا ويسمح طريقة API لتشغيله مرة أخرى، ولكن أنا لا أرى واحدة في adodbapi.

وأنت قد تكون قادرة على استخدام الخاصية conn.adoConn الإختراق حول هذا، وذلك باستخدام واجهة برمجة التطبيقات ADO بدلا من DB-API ليأخذك من أي صفقة. اسمحوا لي أن أعرف إذا كان هذا يعمل:

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

وهنا يكمن مصدر في adodbapi ارتكاب () طريقة .

نصائح أخرى

وقال "المشكلة هي أن DBAPI بيثون يتطلب أن cursor.execute) تكون ملفوفة (في المعاملات التي تلتزم فقط من قبل cursor.commit ()"

و"وأنت لا يمكن تنفيذ قطرة أو إنشاء قاعدة بيانات بيان في معاملة مستخدم."

ولست متأكدا من كل هذا هو في الواقع ينطبق على كافة الواجهات DBAPI.

ومنذ كنت لا تظهر رسائل الخطأ، قد يتبين أن هذا غير صحيح لواجهة ADODBAPI. هل فعلا حاولت ذلك؟ إذا كان الأمر كذلك، ما هي الرسالة الخطأ التي تظهر لك؟

واتصال قد لا <م> دائما يكون خلق "معاملة المستخدم". يمكنك غالبا الاتصالات المفتوحة مع autocommit=True للحصول على AUTOCOMMIT على غرار 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 للقيام بكل الجداول، وغيرها، وارتكاب تلك المعاملة.

وكان هذا العدد نفسه بينما كان يحاول الأوامر دهس adodbapi (مثل CHECKDB DBCC ...) والمشورة 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 القياسية SQL Server تلقائيا. الجانب السلبي هو أن لا توجد وسيلة بالنسبة لي للمعاملات تمكين مرة أخرى (في الوقت الحاضر) اذا كنت wan't لتشغيل شيء داخل معاملة، منذ Connection.commit() لن تفعل شيئا عندما supportsTransactions == False.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top