Недавно я начал получать сообщение об ошибке, которое мне не удается идентифицировать с проектом Django, использующим SQLite. Связанный ниже проект был / является ранее совместимым с Python 2/3, хотя я в основном запускал его с использованием Python 2. Недавно я переключил большинство своих компьютеров и проектов на использование Python 3 по умолчанию (я знаю, лучше поздно, чем никогда, верно ?). Кроме того, я обновил проект с Django 1.7 до 1.11. После этого проект начал получать ошибку table already exists, но Только при запуске команды migrate с помощью python3.
У меня также Только выдает ошибку при запуске python3 manage.py migrate. Например, python3 manage.py test работает нормально, что немного сбивает с толку, учитывая, что тест сначала запускает миграции. python2 manage.py migrate работает нормально, ошибок нет.
Я запускаю Python 3.6.4, установленный через Homebrew на Mac, и я получил следующую ошибку:
File "/usr/local/lib/python3.6/site-packages/django/db/migrations/recorder.py", line 59, in ensure_schema
raise MigrationSchemaMissing("Unable to create the django_migrations table (%s)" % exc)
django.db.migrations.exceptions.MigrationSchemaMissing: Unable to create the django_migrations table (table "django_migrations" already exists)
Я сталкиваюсь с той же самой проблемой - сломанной с Python 3, но работающей с Python 2 - на нескольких компьютерах, поэтому я полагаю, что кто-то другой увидит ту же проблему. Вы сможете воспроизвести проблему, выполнив следующие действия:
git clone [email protected]:alexdlaird/django-bootstrap-authentication-template-project.git && cd django-bootstrap-authentication-template-projectmake installpython2 manage.py migrate - обратите внимание, что он отлично работаетrm db.sqlite для нового стартаpython3 manage.py migrate - обратите внимание, что он не работает с ошибкой, показанной выше
5x. rm db.sqlite для нового старта
5x. python3 manage.py test - обратите внимание, что он отлично работаетЧтобы увидеть, как миграции выполняются для экземпляра MySQL (проект предполагает, что у вас есть экземпляр Homebrew MySQL по умолчанию, работающий локально, но это можно настроить в .env, если нет), запустите python3 manage.py migrate и обратите внимание, что это отлично работает с Python 2 или 3, поэтому проблема кажется изолированной для миграции SQLite.
Любые идеи? Что я здесь делаю не так?
- .pyc Обновление -
Я выполнил find . -name \*.pyc -delete между выполнением вышеуказанных команд, но это никак не улучшило ситуацию. Это имеет смысл, учитывая, что проблема сохраняется на новом клоне, но я думаю, что мы можем устранить проблему с кешированными файлами Python.
Я немного отладил эту проблему, переходя от 2.7 к 3.6. Я вижу, что проблема связана с именами таблиц - вероятно, с юникодом. Например, просмотр возвращенного get_tables_list в значении python3.6/django/db/backends/sqlite3/introspection.py показывает пустой список (я считаю, что из-за буквы b '' перед строкой, которая захватывает то, что в противном случае должно было бы быть индексом массива), тогда как в том же файле и функции в 2.7 все существующие таблицы возвращаются правильно.






Перед каждой попыткой очищайте кеш миграции django.
find . -path "*/migrations/*.pyc" -delete
Никаких кубиков. Я пробовал это много раз и на чистых клонах, так что это не удивительно. Хорошая мысль!
JFI, если вы запустите python3 manage.py migrate <app_name>, это сработает?
Неа. Я пробовал это как с моими приложениями, так и с очисткой и попыткой предварительно запустить миграцию приложений Django (например, сеансы или их миграцию "auth"). Все миграции получают одну и ту же ошибку.
Наконец нашел. Для других, которые могут столкнуться с подобной проблемой, вот оскорбительные строки в моем проекте, которые мне просто пришлось удалить: https://github.com/alexdlaird/django-bootstrap-authentication-template-project/commit/db16ff88d0d6c25eed38e52bd8332c721ed21e2f?diff=split#diff-e398a065684e871bec352076ea80
Это был артефакт многовекового хака, который использовался для Python 2.5 / 6 и SQLite (см. здесь) - это ни в коем случае не хорошее решение, но, учитывая, что SQLite использовался только для разработки и тестирования, он работал отлично. Это было определенно лучше, чем часами биться головой о несовместимости Unicode Python 2 / SQLite.
Неудивительно, что я давно забыл об этом взломе, и это не приходило мне в голову, пока я не отлаживал код Django (описывается в комментарий выше) и не понял, почему имена строковых таблиц имеют уродливые байтовые оболочки.
Учитывая отсутствие поддержки и некоторую дополнительную отладку, которую я провел, что дает мне уверенность, что это ошибка, связанная с Python 3.x и Django 1.10 и выше, я отправил вопрос в список рассылки пользователей Django ниже. Я обновлю этот вопрос, когда получу ответ. groups.google.com/forum/#!topic/django-users/iUGQpqPEltg