Sql перенесення даних з однієї таблиці в іншу, блог мальцева Артема

Виникла наступна проблема: для деякого додатка потрібно було видалити поле tags = TaggableManager (blank = True) (і відповідно залежність django-taggit). Як завжди, стираю це поле і викликаю makemigration, який зробив свою справу як треба. Але при виклику migrate для іншого проекту з тим же набором міграцій відбувається помилка, що додаток taggit не знайдено для виконання міграцій. Воно, звичайно, і логічно, що міграції вимагатимуть цією програмою.

Зараз я розумію, що просто можна було поправити міграції, де створювалося поле taggit і де воно віддалялося, тому якщо ви так не зробили і у вас змінилася структура даних таблиці, то нижче описані дії можуть допомогти.

Перенесення даних з таблиці різної структури

Припустимо, у нас є додаток projects і таблиця projects_project з полями:

Ми хочемо наступну структуру:

Тим самим ми бачимо такі зміни:

  1. title_in_link перейменувався в hint.
  2. Додалося поле is_boder, при цьому воно обов'язково для заповнення.
  3. border_width, яке може бути порожнім.
  4. Віддалилося поле tags

А тепер "вручну" виправимо структуру таблиці:

  1. Перейменовуємо таблицю: projects_project -> projects_project_old.
  2. Видаляємо все міграції додатки, а також видаляємо відповідні записи міграцій в таблиці django_migrations в базі даних.

І видаляю всі знайдені рядки.

  1. Викликаємо makemigration для формування 0001_initial.py (при цьому розуміємо, що доведеться відновити таблицю за допомогою sql команд).
  2. Викликаємо migrate і дивимося, що в базі даних створилася таблиця projects_project з правильною структурою даних.
  3. Пишемо sql код перенесення даних з projects_project_old в projects_project:

Проаналізуйте приклад: як бачите, йде відповідність полів для заповнення. В інтернеті якісного прикладу я не знайшов, тому-то і народився цей пост, щоб цю справу заповнити :)

Зверніть увагу, що border_width ми можемо не заповнювати, так як воно може бути порожнім, а is_border ми повинні заповнити, але, так як у нас немає інформації про це поле, то найпростіше - це заповнити значенням FALSE для кожного запису. Як варіант потім можна написати django міграцію для заповнення полів TRUE або FALSE в залежності від наявності будь-якого значення в поле border_color, але це вже інша історія.

Ще зверніть увагу на те, що поле order збігається зі службовим словом sql, тому потрібно це поле відокремити подвійними лапками.

  1. Видаляємо таблицю projects_project_old.

От і все. Ще раз повторюся, цей приклад для тих, хто випадково зламав структуру даних таблиці, або міграції поламав або, таким чином як я, видаляв залежності від програми. Це довгий "sql-річний" шлях виправлення структури, тому перш ніж видаляти міграції, спробуйте їх просто поправити :)

Перенесення даних пов'язаних таблиць

Припустимо є таблиця: gallery і picture. Таблиця picture містить зовнішній ключ на таблицю gallery.

Цей випадок трохи по складніше: при спробі виконати 4 крок описаний вище django швидше за все буде лаятися приблизно так:

Для вирішення проблеми потрібно перейменувати індекс:

Це можна зробити за допомогою графічного інтерфейсу pgadmin:

Sql перенесення даних з однієї таблиці в іншу, блог мальцева Артема

Потрібний нам індекс виділено зеленим. Тепер правою кнопкою миші по кліку на індекс викликаємо контекстне меню і вибираємо властивості:

Sql перенесення даних з однієї таблиці в іншу, блог мальцева Артема

Тут потрібно перейменувати індекс, наприклад, дописавши "_old".

Тепер знову намагаємося виконати крок 4 і далі слідуємо іншим вище описаним крокам.

0 з 5 (всього 0 оцінок)

Схожі статті