I inherited some code for an application written for Django 1.4. We need to update the codebase to work with Django 1.7 and eventually 1.8 as the next version of Long Term Support.
In several places, it uses the old style @transaction.commit_manually and with transaction.commit_manually:
I donβt know much about transactions at all, but Iβm trying to understand what they are used for, so I can either delete them (if necessary) or upgrade them to a new set_autocommit(False) or equivalent.
I realized that transaction management in Django <1.5 was not ideal and too complicated for most use cases.
The database connection looks like this without special transaction management. (Using Postgres 9.3)
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': 'dbname', 'USER': 'user', 'PASSWORD': '', 'HOST': 'localhost', 'PORT': '', } }
There is no special transaction middleware.
I find the following view particularly puzzling. (Ed)
@UserRequiredDecorator class XMLModelView(View): @transaction.commit_manually def get(self, request, *args, **kwargs): user = request.user xml_models = models.XMLModel.objects.filter(user=user).order_by('-created').all() if xml_models: xml_model = xml_models[0] model = xml_model.xml_field else: obj = initialize_xml_model(user) model = obj.xml_field transaction.commit() if isinstance(model, unicode): model = model.encode('utf-8') with transaction.commit_manually(): xml = XMLManipulator(model, remove_blank_text=True) xml.insert_user_info(user) xml.whitespace_cleanup() model = xml.tostring() del xml transaction.commit() return HttpResponse(model, content_type='text/xml')
Where initialize_xml_model is a function that accepts a flat XML file (xml model template) and creates a new XMLModel object. And insert_user_info inserts the information stored in the user object into the xml model.
As I read this code,
- We turn off
autocommit using commit_manually - We either get the most recent XMLModel for the user, or
- initialize a new XMLModel object
transaction.commit() saves this in db if there are no errors.- We check to see if our
model an unicode instance and then encodes it (I'm not sure what it does) - We open a new transaction
- Import an XMLManipulator object using
model - Insert material and clean xml
- Assign an xml instance back to
model as a string ( tostring is an XMLManipulator method that preserves style declarations.) - delete
xml object - Commit transaction
After 5. The only thing that deals with db (in reading) is the insert_user_info method.
I do not understand why this happens in a special transaction. No db entry?
There are no other methods in this view, just get it.
Perhaps I missed something important, feel free to ask any questions or get more information.
A transaction is really needed here, and if so, how can this be rewritten in accordance with the new transaction.set_autocommit ?
Any help or pointers are appreciated.