Джанго Юг - таблица уже существует

184

Я пытаюсь начать работу с Югом. У меня была существующая база данных, и я добавил Юг (syncdb, schemamigration --initial).

Затем я обновил models.py, чтобы добавить поле, и запустил ./manage.py schemamigration myapp --auto. Казалось, что он нашел поле и сказал, что я могу применить его с помощью ./manage.py migrate myapp. Но, это дало ошибку:

django.db.utils.DatabaseError: table "myapp_tablename" already exists

tablename - первая таблица, указанная в models.py.

Я запускаю Django 1.2, South 0.7

Теги:
django-south

8 ответов

293
Лучший ответ

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

./manage.py migrate myapp --fake

убедитесь, что схема моделей аналогична схеме таблиц в базе данных.

  • 1
    Понял, спасибо. Это на самом деле миграция, а не схема, но ваш ответ направил меня в правильном направлении.
  • 1
    моя ошибка просто скопировала команду из OP, правильная команда ./manage.py перенести myapp --fake
Показать ещё 6 комментариев
42

Хотя в таблице "myapp_tablename" уже существует ошибка остановки воспроизведения после того, как я сделал. /manage.py мигрировать myapp -fake, показывает DatabaseError нет такого столбца: myapp_mymodel.added_field.

Получается точно такая же проблема!

1. Сначала проверьте номер миграции, который вызывает это. Предположим, что это: 0010.

2. Вам нужно:

./manage.py schemamigration myapp --add-field MyModel.added_field
./manage.py migrate myapp

Если имеется больше одного поля, вам нужно повторить его для каждого поля.

3. Теперь вы приземляетесь с кучей новых миграций, поэтому удалите их файлы из myapp/migrations (0011 и далее, если вам нужно добавить несколько полей).

4. Запустите это:

./manage.py migrate myapp 0010

Теперь попробуйте. /manage.py перенести myapp

Если это не поможет, вы готовы. Просто дважды проверьте, не пропало ли какое-либо поле.

EDIT:

Эта проблема также может возникать, когда у вас есть производственная база данных, для которой вы устанавливаете Юг, а первая, начальная миграция, созданная в других программах, дублирует то, что у вас уже есть в вашем db. Решение здесь намного проще:

  • Подделка первой миграции:

    ./управлять мигрированием myapp 0001 --fake

  • Загрузите остальные миграции:

    ./управлять миграцией myapp

10

Когда я столкнулся с этой ошибкой, у нее была другая причина.

В моем случае Юг каким-то образом оставил в моей БД временную пустую таблицу, которая используется в _ remake_table(). Вероятно, я прервал миграцию таким образом, которого я не должен был. В любом случае каждая последующая новая миграция при вызове _remake_table() вызывала ошибку sqlite3.pypysqlite2.dbapi2.OperationalError: table "_south_new_myapp_mymodel" already exists, потому что она уже существовала и не должна была быть там.

_south_new bit выглядел странно, поэтому я просмотрел свою БД, увидел таблицу _south_new_myapp_mymodel, почесал голову, посмотрел на Южный источник, решил, что это барахло, уронил стол, и все было хорошо.

  • 0
    Это то, что я видел, и если бы я нашел это, я бы сэкономил полчаса мозговых болей. Довольно неприятно - но это временные таблицы миграции, и они остаются во время неудачной миграции, вероятно, для целей проверки. Мой произошел из-за некоторой проблемы целостности БД во время попытки миграции.
  • 0
    Это должно быть выше! Если вы используете транзакции БД без схемы, это может произойти довольно легко
2

Если у вас есть проблемы с вашими моделями, не соответствующими вашей базе данных, например @pielgrzym, и вы хотите автоматически переносить базу данных в соответствии с последним файлом models.py(и удалять любые данные, которые не будут воссозданы с помощью приборов в течение migrate):

manage.py schemamigration myapp --initial
manage.py migrate myapp --fake
manage.py migrate myapp zero
manage.py migrate myapp

Это приведет к удалению и воссозданию таблиц базы данных, которые существуют в вашем последнем файле models.py, поэтому в вашей базе данных могут быть таблицы мусора из предыдущих syncdb или migrate s. Чтобы избавиться от них, перед всеми этими переходами выполните следующие действия:

manage.py sqlclear myapp | manage.py sqlshell

И если это все еще оставляет некоторый CRUFT, лежащий в вашей базе данных, вам нужно сделать inspectdb и создать из него файл models.py (для таблиц и приложения, которые вы хотите очистить), прежде чем делать sqlclear, а затем восстановить исходные models.py перед созданием миграции --initial и перехода на нее. Все это, чтобы избежать беспорядка с особым вкусом SQL, который требуется вашей базе данных.

2

Perform these steps in order may help you:

1) python manage.py schemamigration apps.appname --initial

На следующем этапе создается папка миграции по умолчанию.

2) python manage.py migrate apps.appname --fake

создает фальшивую миграцию.

3) python manage.py schemamigration apps.appname --auto

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

4) python manage.py migrate apps.appname

1

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

./manage.py convert_to_south myapp

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

Команда convert_to_south работает только на первом компьютере, на котором вы его запускаете. После того, как вы перенесли начальные миграции, внесенные в ваш VCS, вам нужно запустить ./manage.py migrate myapp 0001 --fake на всех машинах с копией кодовой базы (убедитесь, что они были современными с моделями и схемой). ref: http://south.readthedocs.org/en/latest/convertinganapp.html

0

Еще одно решение (возможно, временное решение).

$ python manage.py sqlmigrate APP_NAME MIGRATION_NAME

например.,.

$ python manage.py sqlmigrate users 0029_auto_20170310_1117

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

0

Как временное решение, вы можете прокомментировать создание таблицы в миграции script.

class Migration(migrations.Migration):

    dependencies = [
        (...)
    ]

    operations = [
        #migrations.CreateModel(
        #    name='TABLE',
        #    fields=[
        #            ....
        #            ....
        #    ],
        #),
        ....
        ....

Или

Если существующая таблица не содержит строк (пустой), тогда рассмотрите удаление таблицы, как показано ниже. (Это исправление рекомендуется, только если таблица не содержит строк). Также убедитесь, что эта операция выполняется до операции createModel.

class Migration(migrations.Migration):

    dependencies = [
        (...),
    ]

    operations = [
        migrations.RunSQL("DROP TABLE myapp_tablename;")
    ]

Ещё вопросы

Сообщество Overcoder
Наверх
Меню