2015-03-19 5 views
8

Я унаследовал код для приложения, написанного для Django 1.4. Нам нужно обновить кодовую базу для работы с Django 1.7 и в конечном итоге 1.8 в качестве следующей версии Long Term Support.Обновление транзакции.commit_manually() в Django> 1.6

В нескольких местах он использует старый стиль @transaction.commit_manually и with transaction.commit_manually:

я не знаю достаточно о сделках в целом, но я пытаюсь понять, что они используются для, так что я могу либо удалить их (если нет необходимости) или обновить их до новее set_autocommit(False) или эквивалент.

Я понял, что управление транзакциями в Django < 1.5 не было идеальным и слишком сложным для большинства случаев использования.

Соединение с базой данных выглядит так, без специального управления транзакциями. (Использование Postgres 9.3)

DATABASES = { 
    'default': { 
     'ENGINE': 'django.db.backends.postgresql_psycopg2', 
     'NAME': 'dbname', 
     'USER': 'user', 
     'PASSWORD': '', 
     'HOST': 'localhost', 
     'PORT': '', 
    } 
} 

Специального промежуточного программного обеспечения для транзакций нет.

Я нахожу следующее представление особенно озадачивающим. (Edited)

@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') 

Где initialize_xml_model это функция, которая принимает плоский файл XML (XML модель шаблона) и создает новый объект XMLModel. И insert_user_info вставляет информацию, хранящуюся в объекте пользователя, в xml-модель.

Как я прочитал этот код является

  1. Сворачиваем autocommit с commit_manually
    • Мы либо получить самый последний объект XMLModel для пользователя, или
    • инициализировать новый XMLModel объект
  2. transaction.commit() магазины th относится к db, если ошибок нет.
  3. Мы проверяем, если наш model является юникода экземпляр, а затем шифрует его (я не уверен, что это делает именно)
  4. Мы открываем новую транзакцию
  5. объект создании экземпляра XMLManipulator с model
  6. Вставка материала и очистить XML
  7. Присвоить XML экземпляр обратно в model в качестве строки (tostring представляет собой способ, который сохраняет XMLManipulator декларации таблицы стилей.)
  8. удалить xml объект
  9. Совершить транзакцию

После 5. единственное, что имеет дело с БД (в чтении) является метод insert_user_info.

Я действительно не понимаю, почему это происходит в специальной транзакции. Нет записи в db?

Других методов на этом виде нет, только получите.

Возможно, я пропустил что-то важное здесь, не стесняйтесь задавать любые вопросы или для получения дополнительной информации.

Здесь действительно нужна сделка, и если да, то как это можно переписать в соответствии с новыми transaction.set_autocommit?

Любые помощь или указатели будут очень признательны.

ответ

6

Хороший способ сделать это сейчас использует transaction.atomic. В вашем примере я бы сделал:

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