2014-10-11 78 views
25

我对django很新颖,能够在djangoproject.com上完成教程而没有任何错误。我现在通过在http://www.django-rest-framework.org/ 发现的Django REST框架教程,我几乎完成它,只是添加身份验证。现在我越来越:OperationalError,没有这样的列。 Django

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 

我已经看了好几个地方在网络上,不只是计算器的解决方案,它似乎普遍认为,问题是我的数据库,需要删除然后重新做,我已经做了好几次了,教程甚至让我删除了数据库并重新创建了它。 这里是我的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')), 
) 

我很抱歉,如果我发布了一堆不必要的信息。先谢谢你们。

编辑: DB模式:

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); 

做一些挖我发现,删除并重新创建数据库(如教程说要)时,而不是使用makemigrations命令后,它不仅不添加列,但它也不会告诉我,什么是错,运行makemigrations命令时,它告诉我:

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节它将在上面发布相同的消息,但对于owner行。所以它需要highlightedowner的默认值,但我不确定要如何使用它。以及教程也没有帮助我。

+2

如果你删除了数据库和reran syncdb我不希望你有这个问题。你确定你删除了正确的SQLite数据库文件吗? – Alasdair 2014-10-11 09:57:47

+1

我提出了你的问题,不是因为这个问题本身,而是因为你尝试过的细节和前沿性的彻底性。提出的问题并不常见。不幸的是我在手机上,无法给出适当的回应。尽管如此,祝你好运。生病检查后看看如何工作 – skzryzg 2014-10-11 13:46:53

+0

我不知道我可以删除错误的数据库。我运行命令'rm tmp.db',然后运行'python manage。py syncdb'每次我这样做,它都会提示我创建一个超级用户,我这样做。我在同一个终端选项卡中执行此操作,以完成项目的其余部分,同时处于相同的环境中。 – TaylorAllred 2014-10-11 18:43:30

回答

30

当你通过你一定会遇到对迁移的部分教程去了,因为这是在Django的一个主要变化1.7

到的Django 1.7之前,执行syncdb命令从未作出过任何变化有机会销毁当前数据库中的数据。这意味着,如果您为模型执行了syncdb,然后向模型添加了一个新行(有效的新列),那么syncdb不会影响数据库中的更改。

因此,无论你手工丢弃的表,然后再跑去执行syncdb(从头开始重建,丢失任何数据),或者手动输入正确的语句在数据库中添加只列。

然后一个项目走过来叫south其实现迁移。这意味着有一种方法可以向前迁移(并反转,撤销)数据库的任何更改并保持数据的完整性。

在Django 1.7,的south功能被直接集成到django的。处理迁移时,过程有点不同。

  1. models.py进行更改(如常规)。
  2. 创建迁移。这会生成代码从当前状态转到模型的下一个状态。这是通过makemigrations命令完成的。这个命令足够聪明,可以检测到发生了什么变化,并且会创建一个脚本来改变你的数据库。
  3. 接下来,应用与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(不能为null)。

要是你加入从一开始这些领域,就不会有问题,因为表中没有现有行。

但是,如果表已经创建并且添加了不能为空的字段,则必须定义默认值以提供任何现有行 - 否则数据库将不会接受您的更改,因为它们会违反数据完整性约束。

这是命令提示你的内容。您可以告诉django在迁移期间应用默认值,或者您可以在模型本身中给它一个“空白”默认highlighted = models.TextField(default='')

+0

但是,如果我删除表格,不应该也解决问题吗?既然我会重新创建这些表格,那么这些字段将会从那里开始呢?但是在实践中(至少在我这样做的时候,我认为我做对了......)但是现在它仍然行不通,但是,当我运行'makemigrations'命令时,它说一切正常,“没有改变检测到“,但是当我进入shell并查看db模式时,它仍然不显示”所有者“或”突出显示“字段。 – TaylorAllred 2014-10-14 06:38:39

+0

如果删除了表格,则需要再次迁移。应用程序中应该有一个名为migrations的文件夹,查看有多少个迁移。 – 2014-10-14 09:37:11

+0

该教程声明实际上删除sqlite文件,然后运行syncdb来重新创建它。即使在这种情况下,该字段也不是在snippets_snippet表中创建的。 – n4cer500 2014-10-14 13:43:39

6

让我们专注于错误:

Exception Value: no such column: snippets_snippet.owner_id

让我们来看看这是不是真的......

可以使用manage.py命令access your db shell(这将使用settings.py变量,因此你一定要连接到正确的)。

manage.py dbshell

现在,您可以通过键入显示您的表的细节:

.schema TABLE_NAME

或者你的情况:

.schema snippets_snippet

更多sqlite的命令可以发现here或通过发出:

.help

最后,通过键入结束会话:

.quit

这不会让你走出困境,但它可以帮助你知道问题到底出的对:)

运气好工作!

+0

非常感谢您向我展示如何访问sqlite shell(或任何shell已配置)......非常棒,不知道为什么我没有早点了解这些...谢谢! – natureminded 2017-05-13 11:27:49

6

我看到我们在这里有同样的问题,我有同样的错误。我想为将来遇到同样错误的用户编写此代码。 更改您的类片段的模型像@Burhan哈立德说后,必须迁移表:

python manage.py makemigrations snippets 
python manage.py migrate 

,并应解决错误。 享受。

+0

何古什,谢谢!那是我的错...... – VivienG 2017-11-15 12:01:36

0

我也面临同样的问题。

如果你正在添加一个新的字段,那么它会给出错误,因为找不到列。

然后你申请make migration命令和migrate命令 然后还是同样的错误.. EX ...现场

path=models.FilePathField(default='') 

,比apply命令

path=models.FilePathField() 

添加默认值后

python manage.py makemigrations 

    python manage.py migrate 

它可能会帮助您

0

如果您的问题与我的一样,那么这是一种解决方法。 好消息是,你不必删除你的分贝。

检查是否没有其他模型将此模型用作参考。

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')},) 

我的解决办法是:从settings.py

  1. 注释掉其他应用程序(在这种情况下,农资)
  2. python manage.py makemigrations; python manage.py migrate
  3. 取消注释其他应用程序,所以它的启用再次。
  4. python manage.py makemigrations; python manage.py migrate

从技术上讲,我想我需要改变limit_choices_to引用,以便

0

从布尔汗哈立德的回答和他有关迁移评论摘自:什么工作对我来说是删除“迁移”的内容文件夹与数据库一起,然后运行manage.py migrate。删除数据库是不够的,因为保存了有关迁移文件夹中表结构的信息。

0

你做了一切正确的事情,我已经经历了同样的问题。 首先删除您DB和迁移 我makemigrations解决了我加入我的应用程序的名称:

python manage.py makemigrations appname 
python manage.py migrate 

这肯定会工作。

1

如果您实例化依赖于该表的类(例如,在views.py中),则会发生此错误。

+0

*非常有帮助* - 如果可以的话,会给你更多+ 1。我正在用Django模型创建对象,并在'views.py'中手动实例化了一些类实例,而不是通过表单提交等。一旦我删除了这些创建事件,我就可以'makemigrations'和'migrate '没有'django.db.utils.OperationalError:table {{project}} _ {{app}}没有名为{{field_trying_to_add}}'列的错误。谢谢! – natureminded 2017-05-12 07:12:04

1

解决这类问题的最直接的办法就是以下3个步骤:

  1. 删除应用程序的迁移文件夹/目录下的所有移民相关的文件(这基本上是与0000,0001开始, 0002等)。

  2. 从App目录中删除/重命名名为db.sqlite3的现有数据库文件。

  3. 现在运行以下命令:

    python manage.py migrate

    最后执行

    python manage.py createsuperuser

    执行管理任务(如果你想)。

0

同意瑞诗凯诗。我也试图解决这个问题很长一段时间。这将可以解决任一或两者的方法 - 2

1.Try删除所述应用的迁移文件夹中的迁移(除了INIT的.py) ,然后运行makemigrations命令

2.如果该没有按不行的话,尝试重新命名模型(这是最后的手段,可能会有点混乱,但肯定会起作用。如果django问“你是否重命名模型?只需按N”。)希望它有帮助.. :)