Ошибка Django при использовании Южной миграции: неизвестный столбец в «списке полей» - PullRequest
2 голосов
/ 27 июля 2011

Я столкнулся с проблемой при использовании schemamigration для добавления столбца в мою базу данных. Поле «is_flagged», о котором идет речь, является логическим значением, принадлежащим модели Video в моем приложении «upload». При запуске миграции я получаю следующее:

....:~/..../webapp$ python manage.py schemamigration upload --auto
Traceback (most recent call last):
  File "manage.py", line 14, in <module>
    execute_manager(settings)
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/__init__.py", line 438, in execute_manager
    utility.execute()
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/__init__.py", line 379, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 191, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 219, in execute
    self.validate()
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 249, in validate
    num_errors = get_validation_errors(s, app)
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/validation.py", line 36, in get_validation_errors
    for (app_name, error) in get_app_errors().items():
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/loading.py", line 146, in get_app_errors
    self._populate()
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/loading.py", line 61, in _populate
    self.load_app(app_name, True)
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/loading.py", line 78, in load_app
    models = import_module('.models', app_name)
  File "/usr/local/lib/python2.7/dist-packages/django/utils/importlib.py", line 35, in import_module
    __import__(name)
  File "/home/..../score/models.py", line 43, in <module>
    class Score(models.Model):          # matches with one specific user and one specific video
  File "/home/..../score/models.py", line 45, in Score
    video = models.ForeignKey(Video, default=Video.objects.all()[0])    # default value shouldn't end up in real objects
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py", line 190, in __getitem__
    return list(qs)[0]
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py", line 84, in __len__
    self._result_cache.extend(self._iter)
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py", line 273, in iterator
    for row in compiler.results_iter():
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/sql/compiler.py", line 680, in results_iter
    for rows in self.execute_sql(MULTI):
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/sql/compiler.py", line 735, in execute_sql
    cursor.execute(sql, params)
  File "/usr/local/lib/python2.7/dist-packages/django/db/backends/util.py", line 34, in execute
    return self.cursor.execute(sql, params)
  File "/usr/local/lib/python2.7/dist-packages/django/db/backends/mysql/base.py", line 86, in execute
    return self.cursor.execute(query, args)
  File "/usr/lib/pymodules/python2.7/MySQLdb/cursors.py", line 166, in execute
    self.errorhandler(self, exc, value)
  File "/usr/lib/pymodules/python2.7/MySQLdb/connections.py", line 35, in defaulterrorhandler
    raise errorclass, errorvalue
_mysql_exceptions.OperationalError: (1054, "Unknown column 'upload_video.is_flagged' in 'field list'")

Есть идеи, почему это не позволяет мне мигрировать? То же самое происходит, когда я специально использую --add-field.

Я думаю, что проблема может заключаться в ForeignKey в другом приложении («Score», как вы можете видеть в трассировке), которое ссылается на объект Video. Если это так, как правильно переносить модели, на которые ссылаются ForeignKeys в других приложениях?

Обновление

Я нашел обходной путь, который заключался в том, чтобы закомментировать некорректную строку ForeignKey в «Score», запустить миграцию как обычно и, наконец, раскомментировать строку, даже не перенося сам «Score». Это работает, но это не элегантно, и было бы громоздко, если бы между приложениями было много ForeignKeys. Как я уже говорил, есть ли способ избежать этого автоматически, без необходимости редактировать модель с помощью ForeignKey для модели с новым полем?

Ответы [ 2 ]

5 голосов
/ 21 октября 2011

Не уверен, что это именно то, что вы ищете, но я столкнулся с подобной проблемой, и именно это исправило ее.Если вы изменили свои модели и не обновили базу данных должным образом, вы получите ту же ошибку.Запуск syncdb не изменит таблицы, которые уже были созданы, поэтому, прежде чем вы сможете загрузить любые дополнительные данные, вы должны сбросить базу данных.

python manage.py reset (app_name)

Затем снова синхронизируйте базу данных, и все будет хорошо.

python manage.py syncdb 
5 голосов
/ 28 июля 2011

Проблема не в том, что у вас есть ForeignKey, указывающий на модель, которую вы переносите.Это очень распространенная ситуация, и South определенно справляется с этим.Настоящая проблема в том, что вы делаете что-то очень-очень плохо в этом объявлении FK.

video = models.ForeignKey(Video, default=Video.objects.all()[0])

Это объявление по умолчанию будет выполнять запрос во время импорта и принимать его первое значение.Вещи, которые выполняются во время импорта, являются большими нет-нет (особенно запрос).Так что, когда South импортирует модели, чтобы они могли проанализировать их и сгенерировать схему миграции, выполняется Video.objects.all().Но поскольку модель Video была изменена (вы только что добавили новое поле), которая еще не существует в БД, ORM в Django вызывает ошибку.

Если вы действительно хотите установить это как значение по умолчаниювместо этого используйте вызываемое значение

def get_default_video():
     return Video.objects.all()[0]

...
video = models.ForeignKey(Video, default=get_default_video)

Примечание : хотя я не могу придумать вескую причину, во-первых, для установки первой записи Video в качестве значения по умолчанию длявидео ФК.Что ты пытаешься сделать?

...