2016-01-17 3 views
5

Я вполне уверен в Django, но до недавнего времени в основном полагался на сгенерированные миграции. Я написал небольшую пользовательскую миграцию, и вскоре после того, как мой CI начал жаловаться на тайм-ауты, и в конечном итоге это связано с миграциями из Django во время развертывания.Миграция Django убита

Сначала я смог исправить эту проблему, но я не знаю, что я сделал (если что-нибудь), что отремонтировал ее. Проблема, похоже, связана с каким-то специальным кодом, который я вводил для конкретной миграции. Вот что я знаю:

  • Изначально все было хорошо, но Миграция начала принимать действительно много времени для запуска (относительно) после добавления моего пользовательского кода. Около 10 секунд.
  • Это работает иногда. то есть. Если я запустил миграцию десять раз из командной строки, иногда она будет работать, и иногда она будет терпеть неудачу.

Выход следующим образом (имена приложений вырезав):

[[email protected] myapp]$ ./manage.py migrate 
Operations to perform: 
    Apply all migrations: myapp1, myapp2, myapp3, myapp4 
Running migrations: 
Killed 
  • Сначала я думал, что это было, потому что я использую RunPython запустить функцию Python, которая копирует данные между двумя полями, прежде удаление одного из полей. Документация препятствует его использованию для PostgreSQL, но есть ли лучший способ сделать это?
  • Бизнес-сценарий здесь состоит в том, что у меня было логическое поле, которое мне нужно было переключить на набор параметров (CharField с options). Код проверяет, было ли логическое значение true и задает правильное значение для символьного поля. Я сделал это дважды. В первый раз все закончилось, но я еще не тестировал его в другой базе данных.

Это миграция (имена приложений вырезаны):

from __future__ import unicode_literals 

from django.db import migrations 

def fix_consulting(apps, schema_editor): 
    my_model = apps.get_model("myapp", "MyModel") 
    for m in my_model._default_manager.all(): 
     if m.consulting: 
      m.detail = "CONSLT" 
      m.save() 


class Migration(migrations.Migration): 

    dependencies = [ 
     ('myapp', '0024_auto_20160117_1113'), 
    ] 

    operations = [ 
     migrations.RunPython(fix_consulting,atomic=False), 
    ] 

Мои мысли:

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

  • Если я добавляю заявления печати в начале fix_consulting, они запускаются иногда и убиваются в другое время. Как она стоит, я побежал в 6-8 раз, и он был убит каждый раз, но в разных точках

Другая информация: - Использование Django 1.9 - Использование PostgreSQL 9.4.4 - Ошибка происходит в основном на CentOS, но также OSX

+0

Ее возможно, что ваша машина просто не в состоянии для хранения данных, полученных «все», поэтому возможно, что изменение всего цикла на «my_model._default_manager.filter (consulting = True) .update (detail =« CONSLT ») может решить проблему ... я бы будьте счастливы ответить на этот вопрос, если я верю – Sayse

+1

Я сделаю это! Это сервер с довольно небольшим объемом памяти. –

+1

Вы правы! Ошибка была в два раза. Как только я изменил его на код, который вы предоставили, он обнаружил еще одну ошибку, которая была решена довольно легко, потому что она фактически дала мне трассировку стека. Спасибо! Идем дальше и добавляем ответ. –

ответ

7

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

def fix_consulting(apps, schema_editor): 
    my_model = apps.get_model("myapp", "MyModel") 
    my_model._default_manager.filter(consulting=True).update(detail="CONSLT") 

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

Забегая вперед, я бы рекомендовал пытаться всегда отфильтровывать то, что возвращается из БД только, что это на самом деле нужен (будь то путем сплайсинга или фильтрации)

Смежные вопросы