OperationalError,没有这样的列。 Django的

时间:2014-10-11 07:27:33

标签: python django django-rest-framework

我是django的新手,能够在没有任何错误的情况下完成djangoproject.com上的教程。我现在正在浏览http://www.django-rest-framework.org/处的Django REST框架教程。 我几乎完成了它,只是添加了身份验证。现在我得到了:

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

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

编辑: DB Schema:

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

在做了一些挖掘之后,我发现当删除并重新创建db(如教程所说)而不是使用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中的models.py部分发表评论,它会在上面发布相同的消息,但是owner行。所以它想要highlightedowner的默认值,但我不确定要使用什么。除了教程也没有帮助我。

28 个答案:

答案 0 :(得分:37)

在阅读本教程时,您必须遇到有关迁移的部分,因为这是django 1.7中的主要变化之一

在django 1.7之前,syncdb命令从未进行任何有可能破坏当前数据库中数据的更改。这意味着如果您为模型执行了syncdb,然后向模型添加了一个新行(实际上是一个新列),syncdb不会影响数据库中的更改。

因此,您要么手动删除该表,然后再次运行syncdb(从头开始重新创建,丢失任何数据),要么手动在数据库中输入正确的语句以仅添加该列。

然后出现了一个名为south的项目,它实现了迁移。这意味着有一种方法可以向数据库迁移(和反向,撤消)任何更改,并保持数据的完整性。

在django 1.7中,south的功能直接集成到django中。使用迁移时,过程有点不同。

  1. models.py进行更改(正常)。
  2. 创建迁移。这会生成从当前状态到模型的下一个状态的代码。这是通过makemigrations命令完成的。此命令足够智能,可以检测已更改的内容,并将创建一个脚本以对数据库进行更改。
  3. 接下来,您将该迁移应用于migrate。此命令按顺序应用所有迁移。
  4. 因此,您的正常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)
    

    在此模型中,您需要两个字段highlightedcode(它们不能为空)。

    如果您从一开始就添加了这些字段,那么就不会有问题,因为该表没有现有的行。

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

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

答案 1 :(得分:8)

让我们关注错误:

  

异常值:   没有这样的专栏: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

这并没有让你走出困境,但它可以帮助你了解问题的终点:)

祝你好运!

答案 2 :(得分:6)

我看到我们在这里遇到同样的问题,我有同样的错误。我想为将来会遇到同样错误的用户写这个。 在改变你的类Snippet模型之后,像@Burhan Khalid所说,你必须迁移表:

python manage.py makemigrations snippets
python manage.py migrate

这应该可以解决错误。 享受。

答案 3 :(得分:4)

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

答案 4 :(得分:3)

解决此类问题的最直接方法是以下3个步骤:

  1. 从App的迁移文件夹/目录中删除所有与迁移相关的文件(这些文件基本上以0000,0001,0002等开头)。

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

  3. 现在运行以下命令:

    python manage.py migrate

    最后执行

    python manage.py createsuperuser

    执行管理任务(如果需要)。

答案 5 :(得分:1)

1.首先从迁移文件中只删除0001_initial.py

2.删除dbsqulite文件

3.python manage.py makemigrations appname

4.python manage.py migrate

终于解决了

答案 6 :(得分:1)

我做了以下

  1. 删除我的db.sqlite3数据库
  2. python manage.py makemigrations
  3. python manage.py migrate

它更新了数据库并修复了问题,而不会影响我的项目。请注意,您可能需要执行python manage.py createsuperuser,因为这会影响所有正在创建的对象。

答案 7 :(得分:0)

每当您添加新字段时,您也需要在数据库中进行更改,因此您需要运行一些命令来添加新列

python manage.py makemigrations
python manage.py migrate
python manage.py runserver

如果它仍然不起作用,请删除名称以 00 开头的迁移文件,并从上面运行相同的命令。如果它仍然不起作用。从您的项目中删除 SQLite 数据库并再次运行这些命令

答案 8 :(得分:0)

我添加这个是因为,如果您的问题仍然存在,则可能是您试图在类的 init 函数中访问数据库。 makemigrations 过程会检查您的所有模块和类,如果您尝试在 init 函数中访问数据库中的表,它可能会引发错误。注释掉该行,然后尝试 makemigrations 和 migrate

答案 9 :(得分:0)

不要像某些人所说的那样删除任何现有的迁移,而是这样做:

python manage.py migrate --fake #(only if the below commands don't work)
python manage.py migrate --run-syncdb
python manage.py runserver makemigrations
python manage.py runserver

答案 10 :(得分:0)

我对 sqlite 有同样的问题。我的models.py 看起来没问题。我做了以下事情:

sqlite3 db.sqlite3
.tables
PRAGMA table_info(table_name);

通过 PRAGMA,我能够看到失败的表中缺少列。 我删除了应用程序中的所有表。小心,因为这会丢失表格中的数据。

DROP table table_name
.quit

然后这样做:

python manage.py makemigrations your_app
python manage.py migrate your_app
python manage.py sqlmigrate your_app 0001

然后再次进入sqlite,粘贴从sqlimigrate得到的所有代码:

sqlite3 db.sqlite3

举个例子,这是我在sqlite中粘贴的内容:

CREATE TABLE "adpet_ad" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "title" varchar(200) NOT NULL, "breed" varchar(30) NULL, "weight" decimal NULL, "age" integer NULL, "text" text NOT NULL, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL, "picture" BLOB NULL, "content_type" varchar(256) NULL, "name" varchar(100) NULL, "phone" varchar(31) NOT NULL, "gender_id" integer NULL REFERENCES "adpet_gender" ("id") DEFERRABLE INITIALLY DEFERRED, "owner_id" integer NOT NULL REFERENCES "auth_user" ("id") DEFERRABLE INITIALLY DEFERRED, "size_id" integer NULL REFERENCES "adpet_size" ("id") DEFERRABLE INITIALLY DEFERRED, "specie_id" integer NULL REFERENCES "adpet_specie" ("id") DEFERRABLE INITIALLY DEFERRED, "sterilized_id" integer NULL REFERENCES "adpet_sterilized" ("id") DEFERRABLE INITIALLY DEFERRED, "vaccinated_id" integer NULL REFERENCES "adpet_vaccinated" ("id") DEFERRABLE INITIALLY DEFERRED);

答案 11 :(得分:0)

删除 django 应用程序的迁移文件夹中的所有迁移,然后运行 ​​makemigrations 和迁移命令。你应该能够走出困境。

答案 12 :(得分:0)

我认为您已跳过此步骤...运行以下命令以查看是否忘记了执行它们...对我有用。

$ python manage.py makemigrations

$ python manage.py migration

谢谢。

答案 13 :(得分:0)

我简单地犯了一个粗心的错误,即在进行迁移后忘记实际应用迁移(迁移)。写这个只是为了以防有人犯同样的错误。

答案 14 :(得分:0)

任何人都来这里

删除所有迁移 删除db.sqlite文件

重做迁移

答案 15 :(得分:0)

如果@Burhan Khalid说了什么之后错误仍然存​​在

尝试以下行:python manage.py migration --run-syncdb

答案 16 :(得分:0)

您没有迁移对模型所做的所有更改。所以 1)python manage.py makemigrations 2)python manage.py migrate 3)python manag.py runserver 它可以100%工作

答案 17 :(得分:0)

就我而言,在admin.py中,我从添加了新ForeignKey字段的表中查询。因此,注释掉admin.py,然后像往常一样运行makemigrations和migrate命令。最后取消注释admin.py

答案 18 :(得分:0)

请记住,在migrations文件夹中隐藏了一个 pycache 文件夹,因此,如果您更改模型并删除所有迁移文件,则还必须删除 pycache 文件夹。 / p>

您唯一不应删除的文件是 init 文件。

希望这会有所帮助

答案 19 :(得分:0)

即使在其他教程上,我最近也遇到了这个问题。我有Django版本2.2.3,所以我认为我不应该遇到这种问题。 就我而言,一旦我向模型添加新字段并尝试在admin中访问它,它将显示为no such column。 在寻找解决方案三天后,我却学到了“正确”的方法,但没有任何效果。 首先,如果要更改模型,则应确保服务器未运行。这就是造成我自己的问题的原因。 这不容易纠正。我必须重命名该字段(服务器未运行时),然后重新应用迁移。 其次,我发现python manage.py makemigrations <app_name>捕获了更改,而不仅仅是python manage.py makemigrations。我不知道为什么 您也可以使用python manage.py migrate <app_name>跟进。我很高兴自己发现了这个问题。

答案 20 :(得分:0)

步骤1:删除db.sqlite3文件。

第2步:$ python manage.py migration

第3步:$ python manage.py makemigrations

第4步:使用$ python manage.py createsuperuser创建超级用户

新的db.sqlite3将自动生成

答案 21 :(得分:0)

最初,我已经注释了导致这些错误的新字段,然后运行 python manage.py makemigrations 然后运行 python manage.py migration 来删除这些新字段领域。

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

然后我重新注释它们并运行 python manage.py makemigrations python manage.py migration 并开始运行。它为我工作。 :)

答案 22 :(得分:0)

我遇到了这个问题,这就是我解决它的方法。

1)从应用的迁移目录中删除所有迁移记录。这些是名为0001_,0002_,0003_等的文件。小心不要删除  _init__.py文件。

2)删除db.sqlite3文件。它将在以后重新生成。

现在,运行以下命令:

python manage.py makemigrations appname
python manage.py migrate

确保在makemigrations之后写下您的应用程序的名称。您可能必须创建超级用户才能再次访问您的数据库。通过以下方式执行此操作

python manage.py createsuperuser

答案 23 :(得分:0)

同意瑞诗凯诗。我也试图解决这个问题很长一段时间。这将通过2种方法中的任何一种或两种来解决 -

1.尝试删除应用迁移文件夹中的迁移( init .py除外)   然后运行makemigrations命令

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

答案 24 :(得分:0)

你做的每件事都是正确的,我也经历过同样的问题。 首先删除db和迁移 我在makemigrations中解决了我添加的应用名称:

python manage.py makemigrations appname
python manage.py migrate

这肯定会奏效。

答案 25 :(得分:0)

取自Burhan Khalid的回答和他关于迁移的评论:对我有用的是删除“migrations”文件夹的内容以及数据库,然后运行manage.py migrate。由于迁移文件夹中有关表结构的已保存信息,因此删除数据库是不够的。

答案 26 :(得分:0)

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

检查是否有其他模型使用此模型作为参考。

django.db.utils.OperationalError: no such column: parts_part_type.blah

这只发生在我身上,因为我有另一个名为&#34; product&#34;在另一个名为&#34; products&#34;引用了这个模型。

part = models.ForeignKey("parts.Part", related_name="some part", limit_choices_to={'part_type':Part_Type.objects.get(prefix='PART')},)

我的解决方案是:

  1. settings.py
  2. 中注释掉其他应用(在本例中为prodcuts)
  3. python manage.py makemigrations; python manage.py migrate
  4. 取消评论其他应用,以便再次启用。
  5. python manage.py makemigrations; python manage.py migrate
  6. 从技术上讲,我认为我需要更改limit_choices_to引用

答案 27 :(得分:0)

我也面临同样的问题。

如果您要添加新字段,则会显示错误,因为找不到任何列。

然后在make migration命令之后应用migrate命令 然后还是一样的错误.. EX ...

 path=models.FilePathField()

添加字段

的默认值
  path=models.FilePathField(default='')

并应用命令

  python manage.py makemigrations

  python manage.py migrate

它可能对你有帮助