Update transaction.commit_manually () to Django> 1.6

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.

+8
python xml django transactions
source share
1 answer

A good way to do this now is to use transaction.atomic. In your example, I would do:

 from django.db import transaction @UserRequiredDecorator class XMLModelView(View): def get(self, request, *args, **kwargs): with transaction.atomic(): 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 if isinstance(model, unicode): model = model.encode('utf-8') with transaction.atomic(): xml = XMLManipulator(model, remove_blank_text=True) xml.insert_user_info(user) xml.whitespace_cleanup() model = xml.tostring() del xml return HttpResponse(model, content_type='text/xml') 
+6
source share

All Articles