Проблема параллелизма 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)


arrow_upward
4
arrow_downward

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

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

arrow_upward
2
arrow_downward

Вы используете 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

arrow_upward
2
arrow_downward

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

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

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

person monkut    schedule 22.02.2009

arrow_upward
1
arrow_downward

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

person Ali Afshar    schedule 21.02.2009