Транзакции pyodbc в представлении Django фиксируют изменения, несмотря на попытки откатаPython

Программы на Python
Ответить
Anonymous
 Транзакции pyodbc в представлении Django фиксируют изменения, несмотря на попытки отката

Сообщение Anonymous »

Я работаю над приложением Django, в котором использую pyodbc для подключения к базе данных AWS RDS SQL Server. Мне нужно запустить серию необработанных SQL-запросов (включая INSERT, UPDATE, DELETE, DISABLE или ENABLE триггера и т. д.) как транзакцию, гарантируя, что никакие изменения не будут зафиксированы, если во время выполнения возникнет какая-либо ошибка. Однако я столкнулся с проблемой, когда изменения фиксируются в базе данных даже при возникновении ошибки, и я вызываю функцию отката().
Вот что я пробовал до сих пор:
Установите autocommit = False для соединения pyodbc, чтобы предотвратить автоматическую фиксацию.
Использовалось несколько курсоров для разных операторов SQL, все под одним и тем же соединением с autocommit = False.
Обернул Представление Django с @transaction.non_atomic_requests, чтобы отключить обработку транзакций Django по умолчанию.
Также попробовал обернуть код с помощью transaction.atomic(), чтобы посмотреть, может ли помочь управление транзакциями Django.
Несмотря на все эти усилия, изменения все еще фиксируется в базе данных после возникновения ошибки в представлении Django, но когда я запускаю тот же код в автономном скрипте Python (вне Django), откат работает отлично, и никакие изменения не фиксируются.
Вот упрощенная версия кода, который я использую:

Код: Выделить всё

import pyodbc
from django.conf import settings
from django.db import transaction

@transaction.non_atomic_requests  # Tried this to disable Django transaction wrapping
def my_view(request):
connection = pyodbc.connect(settings.DATABASE_CONNECTION_STRING, autocommit=False)
try:
# Start transaction
cursor1 = connection.cursor()
cursor1.execute("UPDATE my_table SET column1 = 'value1' WHERE id = 1")

cursor2 = connection.cursor()
cursor2.execute("INSERT INTO my_table (column1) VALUES ('value2')")

# This line will cause an error
cursor3 = connection.cursor()
cursor3.execute("INVALID SQL STATEMENT")  # This should trigger a rollback

# Commit if all queries succeed
connection.commit()

except Exception as e:
print("Error occurred, rolling back transaction:", e)
connection.rollback()  # This should prevent any changes from being committed

finally:
cursor1.close()
cursor2.close()
cursor3.close()
connection.close()

Сводка проблемы:
Когда я запускаю этот код как отдельный скрипт вне Django, он работает должным образом, без каких-либо изменений в случае возникновения ошибки. .
Когда я запускаю тот же код в представлении Django, изменения фиксируются, даже если возникает ошибка.
Дополнительные примечания:
Я знаю, что Django по умолчанию оборачивает представления в транзакции, поэтому я попробовал @transaction.non_atomic_requests, чтобы предотвратить обработку транзакций Django.
Я подтвердил, что для параметра autocommit установлено значение False в соединении pyodbc.
Вопросы:
1) Есть ли что-то в жизненном цикле запроса Django или промежуточном программном обеспечении, которое может мешать моей ручной обработке транзакций?
2)Есть ли способ гарантировать правильную работу функцииrollback() в этой настройке?
3)Есть ли какие-либо конкретные настройки или подходы в Django, которые могут предотвратить внесение этих изменений привержены?
Буду признателен за любые рекомендации по этому вопросу. Спасибо!

Подробнее здесь: https://stackoverflow.com/questions/791 ... back-attem
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»