Isolated Database Connections in Django
Here is an interesting thing to happen while working with Django. I don’t have a clear cut answer for why it happened, but at least I’ve found a work around until I get more information. I think I have an answer for this - connections are open and held through the life of a request. The isolation (I) in ACID keeps other connections isolated from what has happend. I think. That explains why closing the database connection fixes everything. But more on that later…
I have one handler that pulls in data from a 3rd party source and then saves it into a database. This source has their own primary key, so I am using that as the primary key for my table. Last night I ran into something funny.
Two requests come in to pull and save the exact same data. Request 1 comes in, pulls the data and saves it with no problem. Request 2 comes in, pulls the data, tries to save and Django raises and IntegrityError (since the primary key is already in the database). Fine, that’s no problem. I have the key I want, I should be able to just pull the data from my database then, right? Wrong.
When request 2 tries to pull the record, Django raises a Matching query does not exist error, even though the record I want is in the database (presumably, i mean why else would Django first throw that IntegrityError?).
I can get around this by closing the database connection manually and THEN pulling the info i need from the database.
{% codeblock Manually close the database connection lang:python%} from django import db db.close_connection() obj = ObjectIWant.objects.get(pk=id) {% endcodeblock %}
Closing the database connect and having Django reopen it doesn’t cause the Matching query does not exist error. Like I said, I don’t know why this happened. I have hypotheses. I hope to find an answer and come back to share it.
For reference, here is the Reddit /r/django post I did to try to solicit answers.