Django: смешанные управляемые и необработанные db коммиты - TransactionManagementError - PullRequest
0 голосов
/ 28 ноября 2010

Я пишу сценарий массовой вставки, используя ORM + Django и нестандартный SQL.Код имеет следующую схему:

import sys, os
from django.core.management import setup_environ
from my_project import settings
from my_project.my_app.models import Model1, Model2
setup_environ(settings)
from django.db import transaction
from django.db import connection

@transaction.commit_manually
def process_file(relevant_file):

    data_file = open(relevant_file,'r')

    cursor = connection.cursor()

    while 1:
        line = data_file.readline()
        if line == '':
            break

        if not(input_row_i%1000):
            transaction.commit()

        if ([some rare condition]):
            model_1 = Model1([Some assignments based on line])
            model_1.save()

        values = [Some values based on line]
        cursor.execute("INSERT INTO `table_1` ('field_1', 'field_2', 'field_3') VALUES (%i, %f, %s)", values)

    data_file.close()
    transaction.commit()

Я получаю следующую ошибку:

django.db.transaction.TransactionManagementError: Transaction managed block ended with pending COMMIT/ROLLBACK

Как мне решить эту проблему?

Ответы [ 3 ]

2 голосов
/ 07 апреля 2012

Использовать Transactions.commit_unless_managed ()

Я написал пост , чтобы объяснить более подробно с примером.

1 голос
/ 02 апреля 2011

Я начал получать это исключение в аналогичных обстоятельствах.ORM django фактически выдавал ошибку django.core.exceptions.ValidationError, потому что дата была неправильно отформатирована.Поскольку я использовал ручную обработку транзакций для пакетной записи в базу данных, код обработки транзакций Django пытался очистить внутри возникшего исключения django.core.exceptions.ValidationError и выдал собственное исключение django.db.transaction.TransactionManagementError.Попробуйте сделать попытку / исключение вокруг кода model_1, чтобы увидеть, не выбрасываются ли другие исключения.Что-то вроде:

try:
    model_1 ...
    model_1.save()
except:
    print "Unexpected error:", sys.exc_info()[0]
    print 'line:', line

, чтобы увидеть, есть ли какие-либо проблемы с входными данными для кода создания объекта.

0 голосов
/ 10 декабря 2010

Вы можете попробовать обходной путь - поместите transaction.commit() сразу после model_1.save().Я думаю, что вам нужно изолировать необработанные и ORM-транзакции.

...