2014-10-11 76 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」。)希望它有幫助.. :)