title: ProgrammingError 'column "scheme_id" of relation "value_calculator_newunit" does not exist' in Django 1.8.3
body: <p>After a lot of Googling I haven't been able to find anything that resolves my specific issue. This person's problem <a href="https://stackoverflow.com/questions/20168582/programmingerror-column-genre-id-of-relation-music-album-does-not-exist-w">appears similar</a> to mine, but it's not a migration issue, as <code>python3 manage.py makemigrations</code> followed by <code>python3 manage.py migrate</code> doesn't resolve the problem (no error messages), nor did resetting the database to an empty state with <code>python3 manage.py flush</code>.</p>
  
  <p>The error occurs whenever I create a Scheme without an associated NewUnit or RefurbUnit and try to view or delete it in the admin interface (consequently it becomes undeleteable even in the shell), or when I try to create a new one with a RefurbUnit or NewUnit, in which case it doesn't get created at all.</p>
  
  <p>The project I'm working on is so far not too different to the completed tutorial; the only substantial difference is in views.py for each project's main app. I'll post the error message and the code for both my project's app and for the tutorial's polls app (just for reference, as I can't find an up-to-date pre-completed tutorial project that you can compare my code against):</p>
  
  <h1>Error Message</h1>
  
  <pre><code>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...
                                                  ^
  </code></pre>
  
  <hr>
  
  <h1>My app's code</h1>
  
  <h2>admin.py</h2>
  
  <pre><code>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)
  </code></pre>
  
  <h2>models.py</h2>
  
  <pre><code>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()
  </code></pre>
  
  <h2>urls.py</h2>
  
  <pre><code>from django.conf.urls import url
  from . import views
  
  urlpatterns = [
      url(r'^$', views.index, name='index'),
      url(r'^(?P&lt;scheme_id&gt;[0-9]+)/$', views.detail, name='detail'),
  ]
  </code></pre>
  
  <h2>views.py</h2>
  
  <pre><code>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})
  </code></pre>
  
  <h2>tests.py</h2>
  
  <pre><code>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"],
              ["&lt;Scheme: Past scheme&gt;"]
          )
  
      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"],
              ["&lt;Scheme: Future scheme&gt;"]
          )
  </code></pre>
  
  <hr>
  
  <h1>Tutorial's polls app code</h1>
  
  <h2>admin.py</h2>
  
  <pre><code>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)
  </code></pre>
  
  <h2>models.py</h2>
  
  <pre><code>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) &lt;= self.pub_date &lt;= 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)
  </code></pre>
  
  <h2>urls.py</h2>
  
  <pre><code>from django.conf.urls import url
  from . import views
  
  urlpatterns = [
      # ex: /polls
      url(r'^$', views.index, name='index'),
      # ex: /polls/5
      url(r'^(?P&lt;question_id&gt;[0-9]+)/$', views.detail, name='detail'),
      # ex: /polls/5/results/
      url(r'^(?P&lt;question_id&gt;[0-9]+)/results/$', views.results, name='results'),
      # ex: /polls/5/vote/
      url(r'^(?P&lt;question_id&gt;[0-9]+)/vote/$', views.vote, name='vote'),
  ]
  </code></pre>
  
  <h2>views.py</h2>
  
  <pre><code>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,)))
  </code></pre>
  
  <h2>tests.py</h2>
  
  <pre><code>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'],
              ['&lt;Question: Past question.&gt;']
          )
  
      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'],
              ['&lt;Question: Past question.&gt;']
          )
  
      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'],
              ['&lt;Question: Past question 2.&gt;', '&lt;Question: Past question 1.&gt;']
          )
  
  
  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)
  </code></pre>
  
  <p>Also, I'm running Linux Mint 17.2 and PostgreSQL 9.3.9.</p>