2016-05-12 4 views
0

Мы изменили нашу базу данных, используя миграции django (django v1.7 +). Данные, существующие в базе данных, более не действительны.Как отключить миграцию базы данных django?

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

Как один:

  1. сдерживаться новую миграцию при загрузке UnitTest

    я нашел some stuff о перекрывая settings.MIGRATION_MODULES, но не мог понять, как использовать его. Когда я проверяю executor.loader.applied_migrations, он все еще перечисляет все. Единственный способ предотвратить новую миграцию - удалить файл; не решение, которое я могу использовать.

  2. создать запись в базе данных UnitTest (используя старую модель)

    Если мы сможем предотвратить миграцию, то это должно быть довольно просто. myModel.object.create(...)

  3. применять миграцию

    Я думаю, что я, вероятно, может решить эту проблему сейчас, когда я нашел test_executor: установить план, указывающий на файл миграции и выполнить его? Хм, да? Есть какой-либо код для этого :-D

  4. подтверждени старые данные в базе данных теперь соответствует новой модели

    Опять же, я ожидаю, что это должно быть довольно легко: просто принести экземпляр, созданный перед миграцией и подтвердить изменился всеми правильными способами.

Таким образом, проблема на самом деле просто разработка как предотвратить UnitTest от применения последней миграции сценарий, а затем применять его, когда мы готовы?


Возможно, у меня неправильный подход? Должен ли я создавать светильники и просто подтвердить, что все они хороши в конце? Устанавливаются ли приборы до того, как миграция будет применена, или после того, как все будет сделано?


С помощью MigrationExecutor и выбрать конкретные миграции с .migrate я был в состоянии, может быть ?, откатить в определенное состояние, затем накат один за одним. Но это вызывает сомнения; в настоящее время преследует SQL-аут из-за отсутствия фактической инструкции ALTER TABLE. Жюри вышло.

+0

Система управления версиями может помочь в этой ситуации. Вам нужно будет поддерживать две ветви со старыми и новыми переходами. Он похож на случай, когда у вас есть отдельные ветви для среды разработки и разработки с различными настройками, кодом и т. Д. – xyres

+0

@xyres, проверяющий различные коммиты, обычно не подпадает под сферу действия unittest. –

ответ

0

Мы использовали следующий код в settings_test.py игнорировать миграции для испытаний:

MIGRATION_MODULES = dict(
    (app.split('.')[-1], '.'.join([app, 'nonexistent_django_migrations_module'])) 
    for app in INSTALLED_APPS 
) 

Идея здесь в том, что ни одно из приложений не имеют папку nonexistent_django_migrations_module, и, таким образом, Джанго будет просто найти не миграции.

+0

Thx. Это работает, чтобы гарантировать, что он не может найти никаких миграций, но, похоже, мало помогает; как мы можем протестировать миграции, если они не могут их найти? –

+0

, по-видимому, я неправильно понял ваш вопрос - вы действительно хотите проверить логику миграции? – zsepi

+0

Да ... тест, который создает базу данных предварительной миграции, переносит ее, а затем проверяет результат. –

0

Я не был в состоянии предотвратить UnitTest от начиная с текущей схемой базы данных, но я считаю, это очень легко вернуться к предыдущим пунктам в истории миграции:

Где «0014_nulls_permitted» является файл в каталоге кочевок ...

from django.db.migrations.executor import MigrationExecutor 
executor.migrate([("workflow_engine", "0014_nulls_permitted")]) 
executor.loader.build_graph() 

NB:запуска executor.loader.build_graph между вызовами executor.migrate кажется очень важной частью завершения Migra Тион и делать вещи ведут себя, как можно было бы ожидать

миграций, которые в настоящее время применяются к базе данных можно проверить что-то вроде:

print [x[1] for x in sorted(executor.loader.applied_migrations)] 

[u'0001_initial', u'0002_fix_foreignkeys', ... u'0014_nulls_permitted'] 

Я создал экземпляр модели с помощью ОРМА затем обеспечиваются база данных были в старом состоянии, запустив некоторый SQL напрямую:

job = Job.objects.create(....) 
from django.db import connection 
cursor = connection.cursor() 
cursor.execute('UPDATE workflow_engine_job SET next_job_state=NULL') 

Отлично. Теперь я знаю, что у меня есть база данных в старом состоянии, и я могу проверить перенаправление вперед. Так где 0016_nulls_banished является миграция файла:

executor.migrate([("workflow_engine", "0016_nulls_banished")]) 
executor.loader.build_graph() 

Миграция 0015 проходит через базу данных превращающего все NULL полей значения по умолчанию. Миграция 0016 изменяет схему. Вы можете разбросать некоторые утверждения печати, чтобы подтвердить, что все происходит так, как вы думаете.

И теперь тест может подтвердить, что миграция сработала. В этом случае убедитесь, что в базе данных нет нулей.

jobs = Job.objects.all() 
self.assertTrue(all([j.next_job_state is not None for j in jobs])) 
Смежные вопросы