Який рекомендований підхід до скидання історії міграції за допомогою Django South?


153

Я накопичив досить багато міграцій, використовуючи South (0.7) та Django (1.1.2), які починають витрачати зовсім небагато часу на мої одиничні тести. Я хотів би скинути базову лінію та розпочати новий набір міграцій. Я переглянув документацію на Південь , здійснив звичайний пошук Google / Stackoverflow (наприклад, "django south (скиньте АБО видалити АБО видалити) історію міграції") і не знайшов нічого очевидного.

Один із підходів, який я розглядав, передбачав би "почати з початку", видаливши "Південь" або "очистивши" історію вручну (наприклад, очистити таблицю db, видалити файли міграції з директора міграцій) і просто перезапустити,

./manage.py schemamigration southtut - початковий

Отже, якщо хтось робив це раніше і має кілька порад / пропозицій, вони будуть дуже вдячні.


іноді потрібно вручну додати __init__.pyдоappname/migrations
laike9m

2
Як скинути міграцію в 1,7 (за допомогою вбудованої міграції)?
Тимо

1
@Timo: docs.djangoproject.com/en/dev/topics/migrations/… може бути підходом. Ви також можете просто видалити свої міграції / каталоги та повторно видавати, ./manage.py makemigrationsале погані речі трапляться, якщо ви не почнете із свіжого db ...
Jocelyn delalande

Я думаю squashmigrations, що правильна відповідь
Хуліо Марінс

Відповіді:


121

EDIT - я розміщую коментар внизу у верхній частині цього, оскільки важливо прочитати його перед> прийнятою відповіддю, що слідує за @andybak

@Dominique: Ваша порада щодо скидання скидання на південь небезпечна і може знищити базу даних, якщо в проекті є додатки сторонніх розробників, які використовують південь, на що вказував @thnee нижче. Оскільки у Вашій відповіді так багато відгуків, я дуже вдячний, якщо Ви можете її відредагувати та додати принаймні попередження про це або (ще краще) змінити її, щоб відобразити підхід @hobs (що так само зручно, але не впливати на інші додатки) - дякую! - chrisv 26 березня 1313 о 9:09

Прийнята відповідь випливає нижче:

По-перше, відповідь автора Півдня :

Поки ви дбаєте про це одночасно на всіх розгортаннях, з цим не повинно виникнути жодних проблем. Особисто я би зробив:

    rm -r appname/migrations/ 
    ./manage.py reset south 
    ./manage.py convert_to_south appname 

(Зверніть увагу, що " reset south" частина очищає записи міграції для ВСІХ додатків, тому переконайтеся, що ви запускаєте інші два рядки для всіх програм або вибираєте вибірково).

convert_to_southВиклик в кінці робить нову міграцію і підроблений застосовує його (так як база даних вже мають відповідні таблиці). Під час процесу не потрібно скидати всі таблиці додатків.

Ось що я роблю на своєму сервері dev + production, коли мені потрібно позбутися всіх цих непотрібних міграцій розробників:

  1. Переконайтеся, що у нас однакова схема БД з обох сторін
  2. видалити кожну папку міграцій з обох сторін
  3. запустити ./manage.py скинути південь (як йдеться у публікації) з обох сторін = очищає південну таблицю *
  4. запустити ./manage.py convert_to_south з обох сторін (прикидається 0001 міграцію)
  5. тоді я можу повторно почати робити міграції та натискати папки міграцій на своєму сервері

* за винятком випадків, коли ви хочете очистити лише один додаток серед інших, якщо це так, вам потрібно буде відредагувати свою таблицю south_history та видалити лише записи про ваш додаток.


2
Для запису відповідь автора Півдня була такою: Поки ви дбаєте робити це на всіх розгортаннях одночасно, з цим не повинно виникнути жодних проблем. Особисто я би зробив: rm -r appname / migrations / ./manage.py reset south ./manage.py convert_to_south appname (Зауважте, що частина "скинути на південь" очищає записи міграції для ВСІХ додатків, тому переконайтеся, що ви або запустите інші два рядки для всіх додатків або видалити вибірково).
Адріан Тісселінг

2
Зауважте також, що якщо ви кинете таблиці, то вам потрібно manage.py schemamigration app name --initialзамість convert_to_south.
Адріан Тісселінг

7
Станом на Django 1.5 команда керування "скидання" відсутня. Натомість вам захочеться зробити щось приблизно south.models.MigrationHistory.objects.all().delete().
Андрій Б.

13
@Dominique: Ваша порада щодо manage.py reset southє небезпечним і може знищити базу даних , якщо є якась - або додаток стороннього використовує півдня в проекті, як відзначило @thnee нижче. Оскільки у Вашій відповіді так багато відгуків, я дуже вдячний, якщо Ви можете її відредагувати та додати принаймні попередження про це або (ще краще) змінити її, щоб відобразити підхід @hobs (що так само зручно, але не впливати на інші додатки) - дякую!
chrisv

3
Чому це було так високо прихильне? Ви майже НІКОЛИ не повинні повністю видаляти свою історичну таблицю south_migrationhistory. Це повністю викрутить будь-які залежні програми з міграціями, які ви не хочете торкатися. Відповідь Хоб - правильна.
Серін

188

Якщо вам потрібно вибірково (лише для однієї програми) скинути міграції, які тривають занадто довго, це працювало для мене.

rm <app-dir>/migrations/*
python manage.py schemamigration <app-name> --initial
python manage.py migrate <app-name> 0001 --fake  --delete-ghost-migrations

Не забудьте вручну відновити будь-які залежності від інших додатків, додавши рядки, як depends_on = (("<other_app_name>", "0001_initial"),("<yet_another_app_name>", "0001_initial"))у <app-dir>/migrations/0001_initial.pyфайл, як перший атрибут у вашому класі міграції трохи нижче class Migration(SchemaMigration):.

Потім можна ./manage.py migrate <app-name> --fake --delete-ghost-migrationsв інших середовищах, відповідно до цієї відповіді . Звичайно , якщо ви підроблені видалення або підроблені migrate zeroвам потрібно вручну видаляти лівої більш таблиць БД з міграцією , як це .

Більш ядерний варіант - перейти ./manage.py migrate --fake --delete-ghost-migrationsна поточний сервер розгортання з подальшим [my] sqldump. Потім трубу, яка скидає в [my] sql, в середовищі, де вам потрібна перенесена, повнонаселена db. Я знаю південне святотатство, але працювало на мене.


2
Мені дуже хочеться - "прийняти models.py як євангеліє, і з цього моменту зробити мене чистою". Таким чином зберігаючи можливість налаштування розгортання з нуля або роботи з існуючого розгортання.
Брайс

1
Ось що це робить.
варильні панелі

2
@hobs Я отримував деякий DependsOnUnknownMigrationчас підробляючи нову початкову міграцію. Завдяки вашому коментарю, я міг би зрозуміти, що я повинен оновлювати depends_onзаяву там, де вона посилається на цю програму. Тут справді найкраща відповідь. Дякую! :)
ман

55

Завдяки відповідям Домініка Гвардіоли та варильних панелей, це допомогло мені вирішити важку проблему. Однак є кілька питань з рішенням, ось мій погляд на це.

Використовувати manage.py reset southце не дуже добре, якщо у вас є будь-які додатки сторонніх розробників, які використовують Південь, наприклад django-cms(в основному все використовує Південь).

reset south видалить усю історію міграції для всіх встановлених програм.

Тепер розглянемо, що ви оновите до останньої версії django-cms, вона буде містити нові міграції на кшталт 0009_do_something.py. Південь, безумовно , буде плутати , коли ви намагаєтеся запустити цю міграцію без необхідності 0001через0008 в історії міграції.

Набагато краще / безпечніше вибірково скинути лише ті програми, які ви підтримуєте .


Перш за все, переконайтеся, що у ваших додатках немає десинхронізації між міграціями на диску та міграціями, виконаними в базі даних. Інакше буде головний біль.

1. Видалити історію міграції для моїх програм

sql> delete from south_migrationhistory where app_name = 'my_app';

2. Видалити міграцію для моїх програм

$ rm -rf my_app/migrations/

3. Створіть нові початкові міграції для моїх додатків

$ ./manage.py schemamigration --initial my_app

4. Підроблене виконання початкових міграцій для моїх додатків

Це вставляє міграції, south_migrationhistoryне торкаючись фактичних таблиць:

$ ./manage.py migrate --fake my_app

Крок 3 та 4 насправді є лише більш тривалим варіантом manage.py convert_to_south my_app, але я вважаю за краще додатковий контроль у такій делікатній ситуації, як зміна виробничої бази.


2
Я відредагував свою відповідь, щоб включити виправлення виявлених проблем (просто здогадуючись на них, виходячи з вашої відповіді), і перевірив її на виробничій базі з мільйонами рядків.
варильні панелі

2
Це майже все, що ми робимо. Якщо ви скористаєтесь опцією --delete-ghost-migrations на кроці 4, ви можете вийти з кроку 1.
Tobych

Ви повинні вказати назви програм прямо, ./manage.py migrate --fakeякщо ви не хочете підробляти інші програми, які міграції очікують на розгляд.
вадим

2
@wadim Отже, крок 0: "переконайтеся, що у вас немає десинхронізації між міграціями на диску та міграціями, виконаними в базі даних".
thnee

@thnee Право. Напевно, варто згадати, що ви переглядаєте всі встановлені програми на кроці 0. Чи знаєте ви про простий спосіб виконати крок 0?
вадим

7

Як і Thnee (див. Її відповідь), ми використовуємо ніжніший підхід до пропозицій автора Південної (Ендрю Годвін), цитованих в інших місцях, і ми розмежовуємо те, що ми робимо з базою коду, від того, що ми робимо до бази даних, під час розгортання. , тому що нам потрібні розгортання для повторення:

Що ми робимо в коді:

# Remove all the migrations from the app
$ rm -fR appname/migrations
# Make the first migration (don't touch the database)
$ ./manage.py schemamigration appname --initial

Що ми робимо до бази даних, коли цей код розгорнуто

# Fake the migration history, wiping out the rest
$ ./manage.py migrate appname --fake --delete-ghost-migrations

Я думаю, що я робив те саме, але видаляючи записи в базі даних вручну, а не використовуючи --delete_ghoist-migrations. Ваш спосіб трохи приємніший.
wobbily_col

1

Якщо ви просто працюєте над машиною розробників, я написав команду управління, яка робить майже все, що запропонував Домінік.

http://balzerg.blogspot.co.il/2012/09/django-app-reset-with-south.html

На відміну від південної пропозиції автора, це НЕ шкодить іншим встановленим програмам, що використовують південь.


І якщо, на відміну від автора, ви хочете зберегти існуючі міграції (тобто ви хочете скинути додаток, а також історію міграції, але зберегти фактичну міграцію), ви можете спробувати це: goo.gl/0ZnWm
mgalgs

1

Далі йде лише в тому випадку, якщо ви хочете скинути всі програми. Будь ласка, створіть резервні копії всіх баз даних перед цією роботою. Також запишіть свою залежність у вихідні файли, якщо такі є.

На цей раз:

(1) find . -type d -name migrations -exec git rm -rf '{}' \;
(2) find . -type d -name migrations -exec rm -rf '{}' \;
(3) ./manage.py schemamigration <APP_NAME> --initial
(4) [GIT COMMIT]

Тестуйте завантажувальний проект перед тим, як натиснути. Потім для кожної локальної / віддаленої машини застосуйте наступне:

(5) [GIT PULL]
(6) ./manage.py reset south
(7) ./manage.py migrate --fake

Зробіть початковий (3) для кожного додатка, який ви хочете повторно включити. Зауважте, що скидання (6) видалить лише історію міграції, тому не шкодить бібліотекам. Підроблені міграції (7) повернуть історію міграції будь-яких встановлених сторонніх додатків.


0

видаліть потрібний файл із папки додатків

екземплярний шлях

 cd /usr/local/lib/python2.7/dist-packages/wiki/south_migrations

Вікі - це моя програма

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.