5

I've done a bit of reading related to the concurrency issues with sqlite, but I don't see how they'd apply to Django since it's inherently single threaded. I'm not using any multiprocess modules either. I have absolutely no experience with concurrent programming either, so if someone can identify WHY the following code is causing an OperationalError: 'database is locked' I'd be grateful.

views.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)

models.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()

The add_active_residents method works fine, until it is called from the views module. Is there an open connection to the database open in the view which prevents writing from the model? Does someone have an explanation why this code will error?

2
  • So does the lock occur every time you call add_active_residents in the view? What exact line is throwing the lock exception (the save?) Does it occur in devserver, or only in a production environment? Commented Feb 21, 2009 at 14:41
  • This is occuring in devserver, and only when the view calls add_active_residents. Calling add_active_residents from the command line doesn't error. Commented Feb 22, 2009 at 3:26

4 Answers 4

5

In the following method function

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()

Why is there a select_related? You only really need the FK's of ssa_res items. Why do additional queries for related items?

Sign up to request clarification or add additional context in comments.

4 Comments

SSA_Resident is the Many2Many table between SSA and Resident, which contains resident and ssa objects. I'm assuming that these objects need to be returned in order to add them to the many2many relationship of Ovramt_Resident.
"I'm assuming..." that's my point. Try taking it out. See what happens.
I'm with S. Lott. Take out the select_related calls, and see if it still locks.
The issue stopped happening after I manually added and saved the result on the command line, and wrote some new code. I'm going to assume this is correct however, but I'll do some more testing later.
2

Are you using Python 2.6?

If so, this is (apparently) a known issue that can be mitigated by adding:

DATABASE_OPTIONS = {'timeout': 30}

to your settings.py

See http://code.djangoproject.com/ticket/9409

1 Comment

I tried that solution and it didn't work. I was hoping that someone would be able to identify, in my code, what might be causing the issue
2

My understanding is that only write operations will result in a db-locked condition. http://www.sqlite.org/lockingv3.html

It's hard to say what the problem is without knowing how django is handling sqlite internally.

Speaking from using sqlite with standard cgi, I've noticed that in some cases it can take a 'long' time to release the lock. You may want to increase the timeout value mentioned by Matthew Christensen.

Comments

1

Sounds like you are actually running a multithreaded application, despite what you say. I am a bit clueless about Django, but I would assume that even though it might be single-threaded, whatever debugging server, or production server you run your application in won't be "inherently single threaded".

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.