Search code examples
djangodjango-modelsdjango-autocomplete-light

ProgrammingError when upgrading from Django 1.8 to 1.9


I have project with multiple apps in it. One of the apps has a Contact model and a Supplier model. The Supplier has a OneToOne relation to the Contact model. Everything worked fine in Django 1.8.11. When I attempt to makemigrations or any other command, I get the following error.

Traceback (most recent call last):
  File "manage.py", line 15, in <module>
    execute_from_command_line(sys.argv)
  File "D:\env\lib\site-packages\django\core\management\__init__.py", line 353, in execute_from_command_line
    utility.execute()
  File "D:\env\lib\site-packages\django\core\management\__init__.py", line 345, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "D:\env\lib\site-packages\django\core\management\base.py", line 348, in run_from_argv
    self.execute(*args, **cmd_options)
  File "D:\env\lib\site-packages\django\core\management\base.py", line 398, in execute
    self.check()
  File "D:\env\lib\site-packages\django\core\management\base.py", line 426, in check
    include_deployment_checks=include_deployment_checks,
  File "D:\env\lib\site-packages\django\core\checks\registry.py", line 75, in run_checks
    new_errors = check(app_configs=app_configs)
  File "D:\env\lib\site-packages\django\core\checks\urls.py", line 13, in check_url_config
    return check_resolver(resolver)
  File "D:\env\lib\site-packages\django\core\checks\urls.py", line 23, in check_resolver
    for pattern in resolver.url_patterns:
  File "D:\env\lib\site-packages\django\utils\functional.py", line 33, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "D:\env\lib\site-packages\django\core\urlresolvers.py", line 417, in url_patterns
    patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
  File "D:\env\lib\site-packages\django\utils\functional.py", line 33, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "D:\env\lib\site-packages\django\core\urlresolvers.py", line 410, in urlconf_module
    return import_module(self.urlconf_name)
  File "c:\python27\Lib\importlib\__init__.py", line 37, in import_module
    __import__(name)
  File "D:\mdjango\mdjango\urls.py", line 32, in <module>
    url(r'^parts?/', include('parts.urls')),
  File "D:\env\lib\site-packages\django\conf\urls\__init__.py", line 52, in include
    urlconf_module = import_module(urlconf_module)
  File "c:\python27\Lib\importlib\__init__.py", line 37, in import_module
    __import__(name)
  File "D:\mdjango\parts\urls.py", line 2, in <module>
    from parts import views, ajax_views
  File "D:\mdjango\parts\views.py", line 9, in <module>
    from parts import forms
  File "D:\mdjango\parts\forms.py", line 17, in <module>
    class PartForm(forms.ModelForm):
  File "D:\mdjango\parts\forms.py", line 20, in PartForm
    class Meta:
  File "D:\mdjango\parts\forms.py", line 26, in Meta
    "/contacts/create/?next=/parts/create", "Add Supplier")
  File "D:\mdjango\general\widgets.py", line 9, in __init__
    super(SelectWithButton, self).__init__(attrs, choices)
  File "D:\env\lib\site-packages\django\forms\widgets.py", line 514, in __init__
    self.choices = list(choices)
  File "D:\env\lib\site-packages\django\db\models\query.py", line 258, in __iter__
    self._fetch_all()
  File "D:\env\lib\site-packages\django\db\models\query.py", line 1074, in _fetch_all
    self._result_cache = list(self.iterator())
  File "D:\env\lib\site-packages\django\db\models\query.py", line 52, in __iter__
    results = compiler.execute_sql()
  File "D:\env\lib\site-packages\django\db\models\sql\compiler.py", line 848, in execute_sql
    cursor.execute(sql, params)
  File "D:\env\lib\site-packages\django\db\backends\utils.py", line 79, in execute
    return super(CursorDebugWrapper, self).execute(sql, params)
  File "D:\env\lib\site-packages\django\db\backends\utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "D:\env\lib\site-packages\django\db\utils.py", line 95, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "D:\env\lib\site-packages\django\db\backends\utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
django.db.utils.ProgrammingError: relation "contacts_supplier" does not exist
LINE 1: ...tacts_supplier"."default_contract_target_id" FROM "contacts_...

Basically, I have a URL file in my Parts app that is importing from parts.views, which is standard Django procedure. The parts.views file is importing from parts.forms, also standard Django procedure. The form that is causing issues is this:

class PartForm(forms.ModelForm):
    class Meta:
        model = Part
        fields = ['supplier', 'number', 'name']
        widgets = {
            'supplier': SelectWithButton(None, Supplier.objects.all(),
                                        "/contacts/create/?next=/parts/create", "Add Supplier")
        }

Here's the SelectWithButton class:

from django.forms import Select
from django.template.loader import get_template


class SelectWithButton(Select):
    def __init__(self, attrs=None, choices=(), btn_url='', btn_txt=''):
        super(SelectWithButton, self).__init__(attrs, choices)
        self.btn_url = btn_url
        self.btn_txt = btn_txt

    def render(self, name, value, attrs=None, choices=()):
        context = {'href': self.btn_url, 'text': self.btn_txt,
                   'select_field': super(SelectWithButton, self).render(name, value, attrs, choices)}
        t = get_template("general\selectWithButton.html")
        return t.render(context)

The error seems to be that it is trying to get all the objects from Supplier before the migrations have been done. But I'm trying to make the migrations, and I'm getting this error. I did read that Django 1.9 now checks the URL files in the manage.py command, but it seems that I have done nothing out of the ordinary. You can read more here on the 1.9.3 page: https://docs.djangoproject.com/en/1.9/releases/1.9.3/

When I comment out the reference to SelectWithButton, I get a similar error on another form that has an autocomplete_light.MultipleChoiceField on it. What am I doing wrong? It works fine in Django 1.8.11.

Here is the other error and form:

Traceback (most recent call last):
  File "manage.py", line 15, in <module>
    execute_from_command_line(sys.argv)
  File "D:\env\lib\site-packages\django\core\management\__init__.py", line 353, in execute_from_command_line
    utility.execute()
  File "D:\env\lib\site-packages\django\core\management\__init__.py", line 345, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "D:\env\lib\site-packages\django\core\management\base.py", line 348, in run_from_argv
    self.execute(*args, **cmd_options)
  File "D:\env\lib\site-packages\django\core\management\base.py", line 398, in execute
    self.check()
  File "D:\env\lib\site-packages\django\core\management\base.py", line 426, in check
    include_deployment_checks=include_deployment_checks,
  File "D:\env\lib\site-packages\django\core\checks\registry.py", line 75, in run_checks
    new_errors = check(app_configs=app_configs)
  File "D:\env\lib\site-packages\django\core\checks\urls.py", line 13, in check_url_config
    return check_resolver(resolver)
  File "D:\env\lib\site-packages\django\core\checks\urls.py", line 23, in check_resolver
    for pattern in resolver.url_patterns:
  File "D:\env\lib\site-packages\django\utils\functional.py", line 33, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "D:\env\lib\site-packages\django\core\urlresolvers.py", line 417, in url_patterns
    patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
  File "D:\env\lib\site-packages\django\utils\functional.py", line 33, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "D:\env\lib\site-packages\django\core\urlresolvers.py", line 410, in urlconf_module
    return import_module(self.urlconf_name)
  File "c:\python27\Lib\importlib\__init__.py", line 37, in import_module
    __import__(name)
  File "D:\mdjango\mdjango\urls.py", line 33, in <module>
    url(r'^transactions?/', include('transactions.urls')),
  File "D:\env\lib\site-packages\django\conf\urls\__init__.py", line 52, in include
    urlconf_module = import_module(urlconf_module)
  File "c:\python27\Lib\importlib\__init__.py", line 37, in import_module
    __import__(name)
  File "D:\mdjango\transactions\urls.py", line 3, in <module>
    from views import *
  File "D:\mdjango\transactions\views.py", line 3, in <module>
    from forms import *
  File "D:\mdjango\transactions\forms.py", line 18, in <module>
    class InventoryTransactionForm(forms.ModelForm):
  File "D:\mdjango\transactions\forms.py", line 32, in InventoryTransactionForm
    required=False)
  File "D:\env\lib\site-packages\autocomplete_light\fields.py", line 74, in __init__
    self.get_choices(autocomplete, registry, widget)})
  File "D:\env\lib\site-packages\autocomplete_light\fields.py", line 82, in get_choices
    return ((a.choice_value(c), a.choice_label(c)) for c in a.choices)
  File "D:\env\lib\site-packages\django\db\models\query.py", line 258, in __iter__
    self._fetch_all()
  File "D:\env\lib\site-packages\django\db\models\query.py", line 1074, in _fetch_all
    self._result_cache = list(self.iterator())
  File "D:\env\lib\site-packages\django\db\models\query.py", line 52, in __iter__
    results = compiler.execute_sql()
  File "D:\env\lib\site-packages\django\db\models\sql\compiler.py", line 848, in execute_sql
    cursor.execute(sql, params)
  File "D:\env\lib\site-packages\django\db\backends\utils.py", line 79, in execute
    return super(CursorDebugWrapper, self).execute(sql, params)
  File "D:\env\lib\site-packages\django\db\backends\utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "D:\env\lib\site-packages\django\db\utils.py", line 95, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "D:\env\lib\site-packages\django\db\backends\utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
django.db.utils.ProgrammingError: relation "parts_sns" does not exist
LINE 1: SELECT "parts_sns"."id", "parts_sns"."sn" FROM "parts_sns"

The form:

class InventoryTransactionForm(forms.ModelForm):
    parent_sn = autocomplete_light.ModelChoiceField(label="Parent SN", autocomplete='InventoryParentSNAutocomplete',
                                                    required=False)
    qty_in = forms.FloatField(label="In", required=False)
    qty_out = forms.FloatField(label="Out", required=False)
    notes = forms.CharField(required=False)
    part = autocomplete_light.ModelChoiceField(autocomplete="StandardAutocomplete")
    document = autocomplete_light.ModelChoiceField(autocomplete="OpenDocumentAutocomplete", required=False)

    # for Qty Out serial numbers
    sns = autocomplete_light.MultipleChoiceField(label="SNs", autocomplete='InventoryQtyOutSNsAutocomplete',
                                                 required=False)
    user = forms.ModelChoiceField(Employee.objects.filter(user__is_active=True))

    class Meta:
        model = Transaction
        fields = ['date', 'usage', 'notes', 'user', 'sns']

Solution

  • Your form is causing the Supplier.objects.all() queryset to be evaluated before the supplier table has been created in the database.

    You can get around this by setting the widget in the form's __init__ method.

    class PartForm(forms.ModelForm):
        class Meta:
            model = Part
            fields = ['supplier', 'number', 'name']
    
        def __init__(self, *args, **kwargs):
            super(PartForm, self).__init__(*args, **kwargs)
            self.fields['supplier'].widget = SelectWithButton(
                None, 
                Supplier.objects.all(),
                "/contacts/create/?next=/parts/create",
                "Add Supplier",
            )