Проблема параллелизма Django и Sqlite

Я немного почитал о проблемах параллелизма с sqlite, но не понимаю, как они применимы к Django, поскольку он по своей сути однопоточный. Я также не использую многопроцессорные модули. У меня также нет абсолютно никакого опыта в параллельном программировании, поэтому, если кто-то может определить, ПОЧЕМУ следующий код вызывает OperationalError: «база данных заблокирована», я был бы признателен.

просмотры.py

def screening(request, ovramt=None):
errors = []
if request.method == "POST":
    form = ScreeningForm(request.POST)
    if form.is_valid():
       print "Woo valid!!"
    return HttpResponse()

else: # GET            
    if ovramt is None:
        o = Ovramt.objects.select_related(depth=1).latest("date_completed")
        print "found?"
        print o.id
    else:
        try:
            o = Ovramt.objects.select_related(depth=1).get(id=ovramt)
        except:
            errors.append("OVRAMT NOT FOUND") 


    if o.residents.count() <= 0:
        o.add_active_residents()
    residents = list(o.residents)

модели.py

def add_active_residents(self):
    ssa_res = SSA_Resident.objects.select_related(depth=1).filter(ssa=self.ssa, active=True)
    for r in ssa_res:
        self.residents.add(r.resident) # Fails Here
    self.save()

Метод add_active_residents работает нормально, пока не будет вызван из модуля представлений. Есть ли открытое соединение с базой данных, открытое в представлении, которое предотвращает запись из модели? У кого-нибудь есть объяснение, почему этот код будет ошибкой?


person Josh Smeaton    schedule 21.02.2009    source источник
comment
Так происходит ли блокировка каждый раз, когда вы вызываете add_active_residents в представлении? Какая именно строка вызывает исключение блокировки (сохранение?) Это происходит на сервере разработки или только в производственной среде?   -  person Matthew Christensen    schedule 21.02.2009
comment
Это происходит в devserver и только тогда, когда представление вызывает add_active_residents. Вызов add_active_ Residents из командной строки не приводит к ошибке.   -  person Josh Smeaton    schedule 22.02.2009


Ответы (4)


В следующей функции метода

def add_active_residents(self):
    ssa_res = SSA_Resident.objects.select_related(depth=1).filter(ssa=self.ssa, active=True)
    for r in ssa_res:
        self.residents.add(r.resident) # Fails Here
    self.save()

Почему есть select_related? Вам действительно нужны только FK ssa_res предметов. Зачем делать дополнительные запросы для связанных элементов?

person S.Lott    schedule 21.02.2009
comment
SSA_Resident — это таблица Many2Many между SSA и Resident, которая содержит резидентные и ssa-объекты. Я предполагаю, что эти объекты необходимо вернуть, чтобы добавить их в отношение many2many Ovramt_Resident. - person Josh Smeaton; 21.02.2009
comment
Я предполагаю... это моя точка зрения. Попробуйте вынуть. Посмотрите, что происходит. - person S.Lott; 21.02.2009
comment
Я с С. Лоттом. Выньте вызовы select_related и посмотрите, блокируется ли он по-прежнему. - person Matthew Christensen; 22.02.2009
comment
Проблема перестала возникать после того, как я вручную добавил и сохранил результат в командной строке и написал новый код. Однако я собираюсь предположить, что это правильно, но я проведу еще несколько тестов позже. - person Josh Smeaton; 22.02.2009

Вы используете Python 2.6?

Если да, то это (очевидно) известная проблема, которую можно устранить, добавив:

DATABASE_OPTIONS = {'timeout': 30}

в ваши настройки.py

См. http://code.djangoproject.com/ticket/9409.

person Matthew Christensen    schedule 21.02.2009
comment
Я попробовал это решение, и оно не сработало. Я надеялся, что кто-то сможет определить в моем коде, что может быть причиной проблемы. - person Josh Smeaton; 21.02.2009

Насколько я понимаю, только операции записи приведут к блокировке базы данных. http://www.sqlite.org/lockingv3.html

Трудно сказать, в чем проблема, не зная, как django обрабатывает sqlite внутри.

Говоря об использовании sqlite со стандартным cgi, я заметил, что в некоторых случаях снятие блокировки может занять «долгое» время. Вы можете увеличить значение времени ожидания, упомянутое Мэтью Кристенсеном.

person monkut    schedule 22.02.2009

Похоже, вы на самом деле запускаете многопоточное приложение, несмотря на то, что вы говорите. Я немного не разбираюсь в Django, но я бы предположил, что даже если он может быть однопоточным, любой сервер отладки или рабочий сервер, на котором вы запускаете свое приложение, не будет «по своей сути однопоточным».

person Ali Afshar    schedule 21.02.2009