LINUX.ORG.RU

DoesNotExist при обращении по ForeignKey объекта ранее полученной выборки после изменений

 ,


0

1

Если я перебираю в цикле выборку объектов из базы, и при обработке одного из объектов выборки изменяю другой объект, также входящий в выборку, меняя его внешний ключ и удаляя сторонний объект, на который ключ указывал перед изменением, то, когда внешний цикл дойдет до измененного объекта - эго экземпляр в выборке все еще содержит старое значение ключа, указывающее на уже удаленный сторонний объект, и при обращении по нему вылетает DoesNotExist.

Пример для наглядности: я перебираю выборку объектов аудиозаписей модели Recording, ссылающихся на объекты музыки Music. При обработке объекта Recording может выполнится условие, требующее объединения некоторых существующих объектов Music; при этом внешние ключи ссылающихся на них Recording надо перенаправить на объединенный объект, а лишние объекты Music, информация из которых перемещена в объединенный - удалить. При этом в оставшейся части выборки Recordings могут оказаться старые экземпляры только что измененных объектов Recordings, ссылающиеся на удаленные при объединении объекты Music, и, когда цикл дойдет до них - вылетит эксепшн.

Как правильно решается эта проблема?

★★
Ответ на: комментарий от zz

Вариант. Но я прикинул, что при дальнейших изменениях алгоритма у меня, возможно, будут меняться еще какие-нибудь данные в других объектах выборки, и сделал в основном цикле перезапрос текущей версии объекта по первичному ключу.

shatsky ★★
() автор топика

Как правильно решается эта проблема?

Можно сделать два вложенных цикла - первый по объектам Music, второй (подцикл) по Recording, ссылающихся на данный Music.

Что-то типа такого:

for i in Music.objects.all():
   for j in i.recording_set.all():
      if condition(j, i):
          i.recording_set.all().update(music_id=new_music_id)
          i.delete()
          break
provaton ★★★★★
()
Последнее исправление: provaton (всего исправлений: 1)
Ответ на: комментарий от provaton

Нельзя. Recording.music nullable, смысл алгоритма - анализ описаний ссылок на аудиозаписи с созданием объектов Music, описывающих исполняемые в них музыкальные произведения.

shatsky ★★
() автор топика
Ответ на: комментарий от shatsky

Значит отдельной итерацией пройтись по Recording.objects.filter(music=None).

provaton ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.