【问题标题】:ProgrammingError 'column "scheme_id" of relation "value_calculator_newunit" does not exist' in Django 1.8.3Django 1.8.3中的ProgrammingError'关系“value_calculator_newunit”的列“scheme_id”不存在'
【发布时间】:2015-10-12 10:11:29
【问题描述】:

经过大量谷歌搜索后,我无法找到任何可以解决我的特定问题的东西。这个人的问题appears similar 是我的,但这不是迁移问题,因为python3 manage.py makemigrations 后跟python3 manage.py migrate 不能解决问题(没有错误消息),也不能用python3 manage.py flush 将数据库重置为空状态.

每当我创建一个没有关联的 NewUnit 或 RefurbUnit 的 Scheme 并尝试在管理界面中查看或删除它(因此,即使在 shell 中它也变得不可删除),或者当我尝试创建一个带有RefurbUnit 或 NewUnit,在这种情况下它根本不会被创建。

到目前为止,我正在进行的项目与已完成的教程并没有太大的不同;唯一的实质性区别在于每个项目的主应用程序的views.py。我将发布我的项目应用程序和教程投票应用程序的错误消息和代码(仅供参考,因为我找不到可以将我的代码与我的代码进行比较的最新预完成教程项目):

错误信息

Environment:


Request Method: POST
Request URL: http://127.0.0.1:8000/admin/value_calculator/scheme/add/

Django Version: 1.8.3
Python Version: 3.4.0
Installed Applications:
('django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'value_calculator')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 'django.middleware.security.SecurityMiddleware')


Traceback:
File "/usr/local/lib/python3.4/dist-packages/django/core/handlers/base.py" in get_response
  132.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python3.4/dist-packages/django/contrib/admin/options.py" in wrapper
  616.                 return self.admin_site.admin_view(view)(*args, **kwargs)
File "/usr/local/lib/python3.4/dist-packages/django/utils/decorators.py" in _wrapped_view
  110.                     response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python3.4/dist-packages/django/views/decorators/cache.py" in _wrapped_view_func
  57.         response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python3.4/dist-packages/django/contrib/admin/sites.py" in inner
  233.             return view(request, *args, **kwargs)
File "/usr/local/lib/python3.4/dist-packages/django/contrib/admin/options.py" in add_view
  1516.         return self.changeform_view(request, None, form_url, extra_context)
File "/usr/local/lib/python3.4/dist-packages/django/utils/decorators.py" in _wrapper
  34.             return bound_func(*args, **kwargs)
File "/usr/local/lib/python3.4/dist-packages/django/utils/decorators.py" in _wrapped_view
  110.                     response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python3.4/dist-packages/django/utils/decorators.py" in bound_func
  30.                 return func.__get__(self, type(self))(*args2, **kwargs2)
File "/usr/lib/python3.4/contextlib.py" in inner
  30.                 return func(*args, **kwds)
File "/usr/local/lib/python3.4/dist-packages/django/contrib/admin/options.py" in changeform_view
  1468.                 self.save_related(request, form, formsets, not add)
File "/usr/local/lib/python3.4/dist-packages/django/contrib/admin/options.py" in save_related
  1102.             self.save_formset(request, form, formset, change=change)
File "/usr/local/lib/python3.4/dist-packages/django/contrib/admin/options.py" in save_formset
  1090.         formset.save()
File "/usr/local/lib/python3.4/dist-packages/django/forms/models.py" in save
  640.         return self.save_existing_objects(commit) + self.save_new_objects(commit)
File "/usr/local/lib/python3.4/dist-packages/django/forms/models.py" in save_new_objects
  771.             self.new_objects.append(self.save_new(form, commit=commit))
File "/usr/local/lib/python3.4/dist-packages/django/forms/models.py" in save_new
  904.             obj.save()
File "/usr/local/lib/python3.4/dist-packages/django/db/models/base.py" in save
  710.                        force_update=force_update, update_fields=update_fields)
File "/usr/local/lib/python3.4/dist-packages/django/db/models/base.py" in save_base
  738.             updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
File "/usr/local/lib/python3.4/dist-packages/django/db/models/base.py" in _save_table
  822.             result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
File "/usr/local/lib/python3.4/dist-packages/django/db/models/base.py" in _do_insert
  861.                                using=using, raw=raw)
File "/usr/local/lib/python3.4/dist-packages/django/db/models/manager.py" in manager_method
  127.                 return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/usr/local/lib/python3.4/dist-packages/django/db/models/query.py" in _insert
  920.         return query.get_compiler(using=using).execute_sql(return_id)
File "/usr/local/lib/python3.4/dist-packages/django/db/models/sql/compiler.py" in execute_sql
  974.                 cursor.execute(sql, params)
File "/usr/local/lib/python3.4/dist-packages/django/db/backends/utils.py" in execute
  79.             return super(CursorDebugWrapper, self).execute(sql, params)
File "/usr/local/lib/python3.4/dist-packages/django/db/backends/utils.py" in execute
  64.                 return self.cursor.execute(sql, params)
File "/usr/local/lib/python3.4/dist-packages/django/db/utils.py" in __exit__
  97.                 six.reraise(dj_exc_type, dj_exc_value, traceback)
File "/usr/local/lib/python3.4/dist-packages/django/utils/six.py" in reraise
  658.             raise value.with_traceback(tb)
File "/usr/local/lib/python3.4/dist-packages/django/db/backends/utils.py" in execute
  64.                 return self.cursor.execute(sql, params)

Exception Type: ProgrammingError at /admin/value_calculator/scheme/add/
Exception Value: column "scheme_id" of relation "value_calculator_newunit" does not exist
LINE 1: INSERT INTO "value_calculator_newunit" ("scheme_id", "D", "f...
                                                ^

我的应用代码

admin.py

​​>
from django.contrib import admin
from .models import Scheme, NewUnit, RefurbUnit

class NewUnitInline(admin.TabularInline):
    model = NewUnit
    extra = 0

class RefurbUnitInline(admin.TabularInline):
    model = RefurbUnit
    extra = 0

class SchemeAdmin(admin.ModelAdmin):
    #fieldsets = [
    #    (None,               {'fields': ['name']}),
    #    ('Date information', {'fields': ['date']}),
    #]
    inlines = [NewUnitInline, RefurbUnitInline]
    list_display = ("name", "date")
    list_filter = ["date"]

admin.site.register(Scheme, SchemeAdmin)

models.py

​​>
from django.db import models

class Scheme(models.Model):
    #scheme_id = models.IntegerField(unique=True, primary_key=True) #Makes absolutely no difference.
    name = models.CharField(max_length=200)
    new_units = models.IntegerField(default=0)
    refurb_units = models.IntegerField(default=0)
    date = models.DateTimeField()
    appraiser = models.CharField(max_length=200, default="Nobody", blank=True)

    #FIXME: This method is now broken due to ForeignKeys in NewUnit and RefurbUnit
    def get_fields(self):
        return [(field.name, field.value_to_string(self)) for field in self._meta.get_fields()]

    def __str__(self):
        return self.name

class NewUnit(models.Model):
    scheme = models.ForeignKey(Scheme)
    D = models.CharField(max_length=200)
    floor_area = models.IntegerField(default=0)
    units = models.IntegerField(default=0)
    build_price_per_m2 = models.FloatField(default=0)
    build_price_per_unit = models.FloatField(default=0)
    affordable_ratio = models.FloatField(default=0) #Actually a percentage field rather than ratio

class RefurbUnit(models.Model):
    scheme = models.ForeignKey(Scheme)
    resale_price = models.FloatField()

    selling_costs = models.FloatField() #This is percentage, and paired with below field which is an absolute figure
    legal_costs = models.FloatField()
    refurbishment_costs = models.FloatField()
    other_costs = models.FloatField()

urls.py

​​>
from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'^$', views.index, name='index'),
    url(r'^(?P<scheme_id>[0-9]+)/$', views.detail, name='detail'),
]

views.py

​​>
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse, Http404

from .models import Scheme, NewUnit, RefurbUnit


def index(request):
    scheme_list = Scheme.objects.order_by("-date")[:5]
    context = {"scheme_list": scheme_list}
    return render(request, "value_calculator/index.html", context)

def detail(request, scheme_id):
    scheme = get_object_or_404(Scheme, pk=scheme_id)
    return render(request, "value_calculator/detail.html", {"scheme": scheme})

tests.py

​​>
import datetime

from django.test import TestCase
from django.core.urlresolvers import reverse
from django.utils import timezone

from .models import Scheme, NewUnit, RefurbUnit

def create_scheme(name, days=0, new_units=0, refurb_units=0, appraiser=""):
    """Days is an offset value from the current date"""
    time = timezone.now() + datetime.timedelta(days=days)
    return Scheme.objects.create(name=name, date=time, new_units=new_units, refurb_units=refurb_units, appraiser=appraiser)

class SchemeMethodTests(TestCase):
    def test_get_fields(self):
        """Test that the types and lengths are correct."""
        scheme = create_scheme("Test")
        data = scheme.get_fields()
        print(data)
        self.assertEqual(len(data), 6)
        self.assertEqual(type(data), list)

        for item in data:
            self.assertEqual(type(item), tuple)

class SchemeViewTests(TestCase):
    def test_index_view_with_no_schemes(self):
        response = self.client.get(reverse('value_calculator:index'))
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "No schemes are available. Please add some via the admin page.")
        self.assertQuerysetEqual(response.context['scheme_list'], [])

    def test_index_view_with_past_date(self):
        create_scheme("Past scheme", days=-30)
        response = self.client.get(reverse('value_calculator:index'))
        self.assertQuerysetEqual(
            response.context["scheme_list"],
            ["<Scheme: Past scheme>"]
        )

    def test_index_view_with_future_date(self):
        create_scheme("Future scheme", days=30)
        response = self.client.get(reverse('value_calculator:index'))
        self.assertQuerysetEqual(
            response.context["scheme_list"],
            ["<Scheme: Future scheme>"]
        )

教程的投票应用代码

admin.py

​​>
from django.contrib import admin
from .models import Choice, Question

class ChoiceInline(admin.TabularInline):
    model = Choice
    extra = 3

class QuestionAdmin(admin.ModelAdmin):
    fieldsets = [
        (None,               {'fields': ['question_text']}),
        ('Date information', {'fields': ['pub_date']}),
    ]
    inlines = [ChoiceInline]
    list_display = ('question_text', 'pub_date', 'was_published_recently')
    list_filter = ['pub_date']
    search_fields = ['question_text']

admin.site.register(Question, QuestionAdmin)

models.py

​​>
import datetime
from django.utils import timezone
from django.db import models

# Create your models here.
class Question(models.Model):
    def __str__(self):
        return self.question_text
    def was_published_recently(self):
        now = timezone.now()
        return now - datetime.timedelta(days=1) <= self.pub_date <= now 

    was_published_recently.admin_order_field = 'pub_date'
    was_published_recently.boolean = True
    was_published_recently.short_description = 'Published recently?'

    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')

class Choice(models.Model):
    def __str__(self):
        return self.choice_text
    question = models.ForeignKey(Question)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

urls.py

​​>
from django.conf.urls import url
from . import views

urlpatterns = [
    # ex: /polls
    url(r'^$', views.index, name='index'),
    # ex: /polls/5
    url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail'),
    # ex: /polls/5/results/
    url(r'^(?P<question_id>[0-9]+)/results/$', views.results, name='results'),
    # ex: /polls/5/vote/
    url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),
]

views.py

​​>
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse, Http404, HttpResponseRedirect
from django.core.urlresolvers import reverse
from django.template import RequestContext, loader
from django.utils import timezone
from django.views import generic

from .models import Choice, Question

class IndexView(generic.ListView):
    template_name = 'polls/index.html'
    context_object_name = 'latest_question_list'

    def get_queryset(self):
        """Return the last five published questions."""
        return Question.objects.filter(
        pub_date__lte=timezone.now()
    ).order_by('-pub_date')[:5] 


class DetailView(generic.DetailView):
    model = Question
    template_name = 'polls/detail.html'

    def get_queryset(self):
        """
        Excludes any questions that aren't published yet.
        """
        return Question.objects.filter(pub_date__lte=timezone.now())


class ResultsView(generic.DetailView):
    model = Question
    template_name = 'polls/results.html'

def index(request):
    latest_question_list = Question.objects.order_by('-pub_date')[:5]
    context = {'latest_question_list': latest_question_list}
    return render(request, 'polls/index.html', context)

def detail(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    return render(request, 'polls/detail.html', {'question': question})

def results(request, question_id):
    response = "You're looking at the results of question %s."
    return HttpResponse(response % question_id)

def vote(request, question_id):
    p = get_object_or_404(Question, pk=question_id)
    try:
        selected_choice = p.choice_set.get(pk=request.POST['choice'])
    except (KeyError, Choice.DoesNotExist):
        # Redisplay the question voting form.
        return render(request, 'polls/detail.html', {
            'question': p,
            'error_message': "You didn't select a choice.",
        })
    else:
        selected_choice.votes += 1
        selected_choice.save()
        # Always return an HttpResponseRedirect after successfully dealing
        # with POST data. This prevents data from being posted twice if a
        # user hits the Back button.
        return HttpResponseRedirect(reverse('polls:results', args=(p.id,)))

tests.py

​​>
import datetime

from django.utils import timezone
from django.test import TestCase
from django.core.urlresolvers import reverse

from .models import Question

def create_question(question_text, days):
    """
    Creates a question with the given `question_text` published the given
    number of `days` offset to now (negative for questions published
    in the past, positive for questions that have yet to be published).
    """
    time = timezone.now() + datetime.timedelta(days=days)
    return Question.objects.create(question_text=question_text,
                                   pub_date=time)


class QuestionViewTests(TestCase):
    def test_index_view_with_no_questions(self):
        """
        If no questions exist, an appropriate message should be displayed.
        """
        response = self.client.get(reverse('polls:index'))
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "No polls are available.")
        self.assertQuerysetEqual(response.context['latest_question_list'], [])

    def test_index_view_with_a_past_question(self):
        """
        Questions with a pub_date in the past should be displayed on the
        index page.
        """
        create_question(question_text="Past question.", days=-30)
        response = self.client.get(reverse('polls:index'))
        self.assertQuerysetEqual(
            response.context['latest_question_list'],
            ['<Question: Past question.>']
        )

    def test_index_view_with_a_future_question(self):
        """
        Questions with a pub_date in the future should not be displayed on
        the index page.
        """
        create_question(question_text="Future question.", days=30)
        response = self.client.get(reverse('polls:index'))
        self.assertContains(response, "No polls are available.",
                            status_code=200)
        self.assertQuerysetEqual(response.context['latest_question_list'], [])

    def test_index_view_with_future_question_and_past_question(self):
        """
        Even if both past and future questions exist, only past questions
        should be displayed.
        """
        create_question(question_text="Past question.", days=-30)
        create_question(question_text="Future question.", days=30)
        response = self.client.get(reverse('polls:index'))
        self.assertQuerysetEqual(
            response.context['latest_question_list'],
            ['<Question: Past question.>']
        )

    def test_index_view_with_two_past_questions(self):
        """
        The questions index page may display multiple questions.
        """
        create_question(question_text="Past question 1.", days=-30)
        create_question(question_text="Past question 2.", days=-5)
        response = self.client.get(reverse('polls:index'))
        self.assertQuerysetEqual(
            response.context['latest_question_list'],
            ['<Question: Past question 2.>', '<Question: Past question 1.>']
        )


class QuestionMethodTests(TestCase):
    def test_was_published_recently_with_future_question(self):
        """
        was_published_recently() should return False for questions whose
        pub_date is in the future.
        """
        time = timezone.now() + datetime.timedelta(days=30)
        future_question = Question(pub_date=time)
        self.assertEqual(future_question.was_published_recently(), False)

    def test_was_published_recently_with_old_question(self):
        """
        was_published_recently() should return False for questions whose
        pub_date is older than 1 day.
        """
        time = timezone.now() - datetime.timedelta(days=30)
        old_question = Question(pub_date=time)
        self.assertEqual(old_question.was_published_recently(), False)

    def test_was_published_recently_with_recent_question(self):
        """
        was_published_recently() should return True for questions whose
        pub_date is within the last day.
        """
        time = timezone.now() - datetime.timedelta(hours=1)
        recent_question = Question(pub_date=time)
        self.assertEqual(recent_question.was_published_recently(), True)

class QuestionIndexDetailTests(TestCase):
    def test_detail_view_with_a_future_question(self):
        """
        The detail view of a question with a pub_date in the future should
        return a 404 not found.
        """
        future_question = create_question(question_text='Future question.',
                                          days=5)
        response = self.client.get(reverse('polls:detail',
                                   args=(future_question.id,)))
        self.assertEqual(response.status_code, 404)

    def test_detail_view_with_a_past_question(self):
        """
        The detail view of a question with a pub_date in the past should
        display the question's text.
        """
        past_question = create_question(question_text='Past Question.',
                                        days=-5)
        response = self.client.get(reverse('polls:detail',
                                   args=(past_question.id,)))
        self.assertContains(response, past_question.question_text,
                            status_code=200)

另外,我正在运行 Linux Mint 17.2 和 PostgreSQL 9.3.9。

【问题讨论】:

  • 这里的代码太多了。当管理员中发生此错误时,您为什么要发布视图和测试?
  • 我发布所有代码只是为了确保我没有遗漏任何相关信息(即使视图和测试不太可能是有用的信息)。
  • 这只能是迁移问题。你试过manage.py makemigrations value_calculator吗?
  • 我刚刚试了一下,得到了No changes detected in app 'value_calculator'

标签: python django postgresql linux-mint


【解决方案1】:

我发现问题出在我在 PostgreSQL 中的数据库上,但不幸的是我不知道到底出了什么问题。我只是删除并使用dropdbcreatedb 重新创建它,然后运行manage.py migrate;我假设manage.py flush 绝对会清除所有错误。

感谢 Daniel Roseman 通过指出这可能只是一个迁移问题来引导我找到解决方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-11
    • 2016-10-01
    • 2018-05-23
    • 1970-01-01
    • 1970-01-01
    • 2021-03-09
    • 1970-01-01
    • 2018-03-10
    相关资源
    最近更新 更多