OperationalError, нет такого столбца. Джанго
Я очень новичок в django и смог закончить учебник на djangoproject.com без каких-либо ошибок. Сейчас я прохожу учебное руководство по DEST-среде Django, которое можно найти по адресу http://www.django-rest-framework.org/. Я почти закончил с этим и только что добавил аутентификацию. Теперь я получаю:
OperationalError at /snippets/
no such column: snippets_snippet.owner_id
Request Method: GET
Request URL: http://localhost:8000/snippets/
Django Version: 1.7
Exception Type: OperationalError
Exception Value:
no such column: snippets_snippet.owner_id
Exception Location: /Users/taylorallred/Desktop/env/lib/python2.7/site-packages/django/db/backends/sqlite3/base.py in execute, line 485
Python Executable: /Users/taylorallred/Desktop/env/bin/python
Python Version: 2.7.5
Python Path:
['/Users/taylorallred/Desktop/tutorial',
'/Users/taylorallred/Desktop/env/lib/python27.zip',
'/Users/taylorallred/Desktop/env/lib/python2.7',
'/Users/taylorallred/Desktop/env/lib/python2.7/plat-darwin',
'/Users/taylorallred/Desktop/env/lib/python2.7/plat-mac',
'/Users/taylorallred/Desktop/env/lib/python2.7/plat-mac/lib-scriptpackages',
'/Users/taylorallred/Desktop/env/Extras/lib/python',
'/Users/taylorallred/Desktop/env/lib/python2.7/lib-tk',
'/Users/taylorallred/Desktop/env/lib/python2.7/lib-old',
'/Users/taylorallred/Desktop/env/lib/python2.7/lib-dynload',
'/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7',
'/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-darwin',
'/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk',
'/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac',
'/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac/lib-scriptpackages',
'/Users/taylorallred/Desktop/env/lib/python2.7/site-packages']
Server time: Sat, 11 Oct 2014 07:02:34 +0000
Я искал в нескольких местах в Интернете, не только StackOverflow для решения, похоже, что в целом проблема с моей базой данных и нужно удалить ее, а затем переделать ее, я делал это несколько раз, учебник даже есть я удалить базу данных и переделать ее в точке. Вот мой models.py
:
from django.db import models
from pygments.lexers import get_all_lexers
from pygments.styles import get_all_styles
from pygments.lexers import get_lexer_by_name
from pygments.formatters.html import HtmlFormatter
from pygments import highlight
LEXERS = [item for item in get_all_lexers() if item[1]]
LANGUAGE_CHOICES = sorted([(item[1][0], item[0]) for item in LEXERS])
STYLE_CHOICES = sorted((item, item) for item in get_all_styles())
class Snippet(models.Model):
owner = models.ForeignKey('auth.User', related_name='snippets')
highlighted = models.TextField()
created = models.DateTimeField(auto_now_add=True)
title = models.CharField(max_length=100, blank=True, default='')
code = models.TextField()
linenos = models.BooleanField(default=False)
language = models.CharField(choices=LANGUAGE_CHOICES,
default='python',
max_length=100)
style = models.CharField(choices=STYLE_CHOICES,
default='friendly',
max_length=100)
class Meta:
ordering = ('created',)
def save(self, *args, **kwargs):
"""
Use the 'pygments' library to create a highlighted HTML
representation of the code snippet.
"""
lexer = get_lexer_by_name(self.language)
linenos = self.linenos and 'table' or False
options = self.title and {'title': self.title} or {}
formatter = HtmlFormatter(style=self.style, linenos=linenos,
full=true, **options)
self.highlighted = highlight(self.code, lexer, formatter)
super(Snippet, self).save(*args, **kwargs)
Мой serializers.py
:
from django.forms import widgets
from rest_framework import serializers
from snippets.models import Snippet, LANGUAGE_CHOICES, STYLE_CHOICES
from django.contrib.auth.models import User
class SnippetSerializer(serializers.ModelSerializer):
owner = serializers.Field(source='owner.username')
class Meta:
model = Snippet
fields = ('id', 'title', 'code', 'linenos', 'language', 'style', 'owner')
class UserSerializer(serializers.ModelSerializer):
snippets = serializers.PrimaryKeyRelatedField(many=True)
class Meta:
model = User
fields = ('id', 'username', 'snippets')
Мои views.py
:
from snippets.models import Snippet
from snippets.serializers import SnippetSerializer
from rest_framework import generics
from django.contrib.auth.models import User
from snippets.serializers import UserSerializer
from rest_framework import permissions
class SnippetList(generics.ListCreateAPIView):
"""
List all snippets, or create a new snippet.
"""
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
def pre_save(self, obj):
obj.owner = self.request.user
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
class SnippetDetail(generics.RetrieveUpdateDestroyAPIView):
"""
Retrieve, update or delete a nippet instance.
"""
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
def pre_save(self, obj):
obj.owner = self.request.user
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
class UserList(generics.ListAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
class UserDetail(generics.RetrieveAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
И наконец мой urls.py
from django.conf.urls import include
from django.conf.urls import patterns, url
from rest_framework.urlpatterns import format_suffix_patterns
from snippets import views
urlpatterns = patterns('',
url(r'^snippets/$', views.SnippetList.as_view()),
url(r'^snippets/(?P<pk>[0-9]+)/$', views.SnippetDetail.as_view()),
url(r'^users/$', views.UserList.as_view()),
url(r'^users/(?P<pk>[0-9]+)/$', views.UserDetail.as_view()),
)
urlpatterns = format_suffix_patterns(urlpatterns)
urlpatterns += patterns('',
url(r'^api-auth/', include('rest_framework.urls',
namespace='rest_framework')),
)
Я прошу прощения, если я разместил кучу ненужной информации. Заранее спасибо, ребята.
Изменение: Схема БД:
CREATE TABLE "snippets_snippet" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
"created" datetime NOT NULL, "title" varchar(100) NOT NULL, "code" text NOT NULL,
"linenos" bool NOT NULL, "language" varchar(100) NOT NULL, "style" varchar(100) NOT NULL);
После некоторого копания я обнаружил, что при удалении и воссоздании БД (как сказано в руководстве) вместо использования команды make migrations
это не только НЕ добавит столбцы, но и не скажет, что что-то не так при запуске make migrations
команда говорит мне:
You are trying to add a non-nullable field 'highlighted' to snippet without a default;
we can't do that (the database needs something to populate existing rows).
Please select a fix:
1) Provide a one-off default now (will be set on all existing rows)
2) Quit, and let me add a default in models.py
Если я закомментирую highlighted
раздел в models.py
он отправит то же сообщение выше, но для строки owner
. Таким образом, он хочет установить значение по умолчанию как для highlighted
и для owner
, но я не уверен, что использовать как его. Кроме того, учебник мне тоже не помогает.
Ответы
Ответ 1
Проходя обучение, вы наверняка сталкивались с разделом о миграции, поскольку это было одним из основных изменений в Django 1.7.
До Django 1.7 команда syncdb никогда не вносила изменений, которые могли уничтожить данные, находящиеся в данный момент в базе данных. Это означало, что если вы сделали syncdb для модели, а затем добавили в модель новую строку (новый столбец, эффективно), syncdb не повлияло бы на это изменение в базе данных.
Таким образом, либо вы удалили эту таблицу вручную, а затем снова запустили syncdb (чтобы воссоздать ее с нуля, потеряв любые данные), либо вы вручную ввели правильные операторы в базу данных, чтобы добавить только этот столбец.
Затем появился проект под названием south
который осуществил миграцию. Это означало, что был способ перенести (и отменить, отменить) любые изменения в базе данных и сохранить целостность данных.
В Django 1.7 функциональность south
была интегрирована непосредственно в Django. При работе с миграциями процесс немного отличается.
- Внесите изменения в
models.py
(как обычно). - Создать миграцию. Это генерирует код для перехода из текущего состояния в следующее состояние вашей модели. Это делается с
makemigrations
команды makemigrations
. Эта команда достаточно умна, чтобы обнаружить то, что изменилось, и создаст сценарий для внесения этих изменений в вашу базу данных. - Затем вы применяете эту миграцию с помощью
migrate
. Эта команда применяет все миграции по порядку.
Таким образом, ваш обычный syncdb
теперь представляет собой двухэтапный процесс: python manage.py makemigrations
за которым следует python manage.py migrate
.
Теперь по вашей конкретной проблеме:
class Snippet(models.Model):
owner = models.ForeignKey('auth.User', related_name='snippets')
highlighted = models.TextField()
created = models.DateTimeField(auto_now_add=True)
title = models.CharField(max_length=100, blank=True, default='')
code = models.TextField()
linenos = models.BooleanField(default=False)
language = models.CharField(choices=LANGUAGE_CHOICES,
default='python',
max_length=100)
style = models.CharField(choices=STYLE_CHOICES,
default='friendly',
max_length=100)
В этой модели highlighted
два поля и обязательный code
(они не могут быть нулевыми).
Если бы вы добавили эти поля с самого начала, не было бы проблемы, потому что в таблице нет существующих строк?
Однако, если таблица уже создана, и вы добавляете поле, которое не может быть пустым, вам нужно определить значение по умолчанию, чтобы обеспечить любые существующие строки - в противном случае база данных не примет ваши изменения, поскольку они нарушат ограничения целостности данных.,
Это то, о чем вам подсказывает команда. Вы можете указать Django применять значение по умолчанию во время миграции или дать ему "пустое" значение по умолчанию highlighted = models.TextField(default='')
в самой модели.
Ответ 2
Давайте сосредоточимся на ошибке:
Значение исключения: такого столбца нет: snippets_snippet.owner_id
Давайте посмотрим, если это правда...
Вы можете использовать команду manage.py для доступа к вашей оболочке db (при этом будут использоваться переменные settings.py, поэтому вы обязательно подключитесь к правильной).
manage.py dbshell
Теперь вы можете показать детали вашей таблицы, набрав:
.schema TABLE_NAME
Или в вашем случае:
.schema snippets_snippet
Больше команд sqlite можно найти здесь или с помощью команды:
.help
Наконец, завершите сеанс, набрав:
.quit
Это не вытащит вас из леса, но поможет вам понять, над каким концом проблемы нужно работать :)
Удачи!
Ответ 3
Я вижу, что у нас такая же проблема, у меня такая же ошибка. Я хочу написать это для будущего пользователя, который будет испытывать ту же ошибку.
После внесения изменений в модель класса Snippet, например @Burhan Khalid, вы должны перенести таблицы:
python manage.py makemigrations snippets
python manage.py migrate
И это должно устранить ошибку.
Наслаждайтесь.
Ответ 4
Эта ошибка может произойти, если вы создаете экземпляр класса, который полагается на эту таблицу, например, в views.py.
Ответ 5
Самый прямой способ решения этого типа проблемы - это всего лишь три этапа:
-
Удалите все файлы, связанные с перенастройкой, из папки/каталогов миграции приложений (они в основном начинаются с 0000, 0001, 0002 и т.д.).
-
Удалить/переименовать существующий файл базы данных с именем db.sqlite3 из каталога приложений.
-
Теперь запустите следующую команду:
python manage.py migrate
Наконец выполните
python manage.py createsuperuser
для выполнения административных задач (если хотите).
Ответ 6
Сначала я прокомментировал мои новые поля, которые вызывают эти ошибки, и запустил pym manage.py makemigrations, а затем python manage.py migrate для фактического удаления этих новых полей.
class FootballScore(models.Model):
team = models.ForeignKey(Team, related_name='teams_football', on_delete=models.CASCADE)
# match_played = models.IntegerField(default='0')
# lose = models.IntegerField(default='0')
win = models.IntegerField(default='0')
# points = models.IntegerField(default='0')
class FootballScore(models.Model):
team = models.ForeignKey(Team, related_name='teams_football', on_delete=models.CASCADE)
match_played = models.IntegerField(default='0')
lose = models.IntegerField(default='0')
win = models.IntegerField(default='0')
points = models.IntegerField(default='0')
Затем я снова раскомментировал их и запустил make-миграции python manage.py и python manage.py migrate и boom. Это сработало для меня. :)
Ответ 7
Шаг 1: Удалите файл db.sqlite3.
Шаг 2: перенос $ python manage.py
Шаг 3: $ python manage.py makemigrations
Шаг 4: Создайте суперпользователя, используя $ python manage.py createuperuser
новый db.sqlite3 будет генерироваться автоматически
Ответ 8
Я также сталкиваюсь с такой же проблемой.
Если вы добавляете новое поле, оно дает ошибку, поскольку столбец не найден.
Затем вы применяете команду make migration
и после этого команду migrate
Тогда еще такая же ошибка..
EX...
path=models.FilePathField()
Добавить значение по умолчанию для поля
path=models.FilePathField(default='')
и примените команду
python manage.py makemigrations
python manage.py migrate
Это может помочь вам
Ответ 9
Если ваша проблема похожа на мою, то это обходное решение.
Хорошей новостью является то, что вам не придется удалять свой db.
Проверьте, нет ли какой-либо другой модели, использующей эту модель в качестве ссылки.
django.db.utils.OperationalError: no such column: parts_part_type.blah
Это происходило только со мной, потому что у меня была другая модель под названием "продукт" в другом приложении под названием "продукты", на которое ссылалась эта модель.
part = models.ForeignKey("parts.Part", related_name="some part", limit_choices_to={'part_type':Part_Type.objects.get(prefix='PART')},)
Мое решение было:
- закомментируйте другое приложение (в данном случае prodcuts) из settings.py
-
python manage.py makemigrations; python manage.py migrate
- не комментируйте другое приложение, чтобы его снова активировали.
-
python manage.py makemigrations; python manage.py migrate
Технически я думаю, мне нужно изменить ссылку limit_choices_to
, чтобы
Ответ 10
Взятый из ответа Бурхана Халида и его комментарий о миграции: то, что сработало для меня, было удаление содержимого папки "миграции" вместе с базой данных, а затем запуск миграции manage.py. Удаление базы данных недостаточно из-за сохраненной информации о структуре таблицы в папке миграции.
Ответ 11
Вы сделали все правильно, я прошел через ту же проблему.
Сначала удалите db и миграции.
Я решил добавить имя моего приложения в makemigrations
:
python manage.py makemigrations appname
python manage.py migrate
Это определенно сработает.
Ответ 12
Согласитесь с Ришикешем. Я тоже пытался решить эту проблему в течение длительного времени. Это будет разрешено одним или обоими из двух методов -
1. Удалите миграцию в папке миграции приложений (кроме init.py) а затем выполните команду makemigrations
2.Если это не работает, попробуйте переименовать модель (это последнее средство и может немного запутаться, но будет работать точно. Если django спрашивает: "Вы переименовали модель? просто нажмите N." ) Надеюсь, это поможет..:)
Ответ 13
Я столкнулся с этой проблемой, и вот как я ее решил.
1) Удалите все записи миграции из каталога миграции вашего приложения. Это файлы с именами 0001_, 0002_, 0003_ и т.д. Будьте осторожны, чтобы не удалить файл _init__.py.
2) Удалите файл db.sqlite3. Это будет восстановлено позже.
Теперь выполните следующие команды:
python manage.py makemigrations appname
python manage.py migrate
Обязательно напишите название своего приложения после makemigrations. Возможно, вам придется создать суперпользователя, чтобы снова получить доступ к вашей базе данных. Сделайте это следующим
python manage.py createsuperuser
Ответ 14
У меня недавно была эта проблема, хотя и в другом уроке. У меня была версия Django 2.2.3, поэтому я подумал, что у меня не должно быть такого рода проблем. В моем случае, как только я добавлю новое поле в модель и попытаюсь получить к нему доступ в admin
, no such column
будет no such column
. Я выучил "правильный" путь после трех дней поиска решения без работы. Во-первых, если вы вносите изменения в модель, вы должны убедиться, что сервер не работает. Это то, что вызвало мою собственную проблему. И это нелегко исправить. Мне пришлось переименовать поле (пока сервер не работал) и повторно применить миграции. Во-вторых, я обнаружил, что python manage.py makemigrations <app_name>
зафиксировал изменение, а не просто python manage.py makemigrations
. Я не знаю почему. Вы также можете выполнить это с помощью python manage.py migrate <app_name>
. Я рад, что узнал это сам.
Ответ 15
просто помните, что внутри папки миграции есть скрытая папка pycache, поэтому, если вы измените свои модели и удалите все файлы миграции, вы ДОЛЖНЫ также удалить папку pycache.
Единственный файл, который вы не должны удалять, - это файл init.
Надеюсь это поможет