Django изменяет on_delete во время выполнения

История

Я делаю приложение Jurnal. В настоящее время работаю над синхронизацией на нескольких машинах. Я хочу синхронизировать модель за моделью, а не всю базу данных сразу. Я даже допускаю синхронизацию всего нескольких записей, изображений: enter image description here

Текущая проблема, с которой я сталкиваюсь, заключается в замене данных модели на новые синхронизированные данные. У меня есть новая база данных для модели (не для всех моделей) в JSON.

Другие модели имеют ForeginKey к изменяемым данным (с on_delete=CASCADE). У меня есть отображение в виде dict {old_pk : new_pk...}. Я буду использовать его для обновления других объектов ForeginKey на синхронизируемые объекты (чьи pk изменятся).

Проблема

Я хочу удалить старую базу данных без CASCADE удаления. Я хочу установить значение on_delete на DO_NOTHING временно, пока не закончу миграцию.

Примечание: ReadAt код содержит:

read_by = models.ForeignKey(
    Person,
    on_delete=models.CASCADE, # change temporarily to DO_NOTHING at runtime
)

Изменяя on_delete во время выполнения, я мог бы сделать:

# DELETE OLD DATA
ReadAt.on_delete=DO_NOTHING # pseudo code I want to achieve

Person.objects.all().delete()  # without code above, this deletes all ReadAt

# LOAD NEW DATA
with open("person_file.json", mode="w+", encoding="utf-8") as myfile:
    myfile.write(json.dumps(data_new_server))
call_command("loaddata", "person_file.json")

# Then fix the PKs of ReadAt with a mapping I have made

ReadAt.on_delete=CASCADE # pseudo code, change back
# ideally check the integrity of ReadAt data now

Альтернатива

Я думал об этом, но застрял:
  1. Найдите максимальное значение импортируемого пк MAX_PK.
  2. Измените все записи PKs в Person (и FK в ReadAt), добавьте к ним MAX_PK.
  3. Импортируйте новые данные (старые и новые данные не должны пересекаться).
  4. Измените PK ReadAt со old_PK на new_PK.
  5. Удалите все Person, чей PK >= MAX_PK, для них нет ForeginKeys после предыдущего шага.

Я думал об этом, но это кажется более сложным, чем то, что я хочу. Это происходит от альтернативы в вопросе:

Дополнительные ограничения на решение:

  • перенумеруйте пк после завершения работы
  • .
  • Используются только две машины, поэтому они будут синхронизироваться только между ними.

Решение:

  1. Найти максимум текущего пк MAX_PK_CURRENT.
  2. Найдите максимум импортированного пк MAX_PK_IPORTED.
  3. MAX_PK = max(MAX_PK_CURRENT, MAX_PK_IPORTED)
  4. Дублировать записи о персонах, дубликаты будут иметь PK=original_pk + MAX_PK
  5. Измените PK в ReadAt со old_PK на duplicate_PK.
  6. Удалите все Person, чей PK < MAX_PK, к ним нет ForeginKeys после предыдущего шага.
  7. Импортируйте новые данные (дубликат и импортированные данные не должны пересекаться).
  8. Измените PK ReadAt с duplicated_PK на new_PK.
  9. Удалите все Person, чей PK >= MAX_PK, для них нет ForeginKeys после предыдущего шага.

Я попробую реализовать это позже.

Вернуться на верх