Opened 8 years ago

Closed 8 years ago

Last modified 8 years ago

#25837 closed Uncategorized (invalid)

migration fails when there is initial option set on form field

Reported by: Rapolas K. Owned by: nobody
Component: Uncategorized Version: 1.9rc1
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

It requires some setup to reproduce it, but essentially: create a new project, create a new app, create a simple form, for example:

from .models import Item

class ReportForm(forms.Form):
    items = forms.ModelMultipleChoiceField(
        queryset=Item.objects.all(),
        widget=forms.CheckboxSelectMultiple,
        initial=[item for item in Item.objects.all()])

Import that form in the view and that view in urls and migration starts to fail, complaining about missing table (django.db.utils.OperationalError: no such table: myapp_item). It does work fine in django 1.8. Attaching sample project. Tested on django 1.9rc2 (dropdown doesn't have that version to select)

Attachments (1)

mysite.tar.gz (2.8 KB ) - added by Rapolas K. 8 years ago.
Sample project

Download all attachments as: .zip

Change History (8)

by Rapolas K., 8 years ago

Attachment: mysite.tar.gz added

Sample project

comment:1 by Marten Kenbeek, 8 years ago

Resolution: invalid
Status: newclosed

You cannot query the database when a file is imported. When you use initial=Item.objects.all(), the query will be lazy, and it won't result in an error. If you need to evaluate the queryset before passing it to initial, you need to do so in the __init__ method of your form.

This probably works fine on 1.8 because you have an existing database in your 1.8 setup. It won't work if you deploy in a new 1.8 environment without an existing database.

comment:2 by Rapolas K., 8 years ago

Have you tried the attached project? It doesn't have any DB inside, and migrations work fine with 1.8 django, but fails with 1.9rc2. So in order to reproduce - download the project, install django 1.8, run ./manage migrate. Works fine. Remove db.sqlite3, install django 1.9rc2, run ./manage migrate. Migrations fail.

comment:3 by Shai Berger, 8 years ago

I took a look through your code, and could not find a reason for your forms to be imported in the migration.

Could you save us the trouble of running it, and just paste your full traceback?

Thanks.

Last edited 8 years ago by Shai Berger (previous) (diff)

comment:4 by Rapolas K., 8 years ago

(venv)➜  mysite $  python manage.py migrate
Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/home/rapolas/temp/mysite/venv/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 350, in execute_from_command_line
    utility.execute()
  File "/home/rapolas/temp/mysite/venv/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 342, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/rapolas/temp/mysite/venv/local/lib/python2.7/site-packages/django/core/management/base.py", line 348, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/home/rapolas/temp/mysite/venv/local/lib/python2.7/site-packages/django/core/management/base.py", line 398, in execute
    self.check()
  File "/home/rapolas/temp/mysite/venv/local/lib/python2.7/site-packages/django/core/management/base.py", line 426, in check
    include_deployment_checks=include_deployment_checks,
  File "/home/rapolas/temp/mysite/venv/local/lib/python2.7/site-packages/django/core/checks/registry.py", line 75, in run_checks
    new_errors = check(app_configs=app_configs)
  File "/home/rapolas/temp/mysite/venv/local/lib/python2.7/site-packages/django/core/checks/urls.py", line 10, in check_url_config
    return check_resolver(resolver)
  File "/home/rapolas/temp/mysite/venv/local/lib/python2.7/site-packages/django/core/checks/urls.py", line 19, in check_resolver
    for pattern in resolver.url_patterns:
  File "/home/rapolas/temp/mysite/venv/local/lib/python2.7/site-packages/django/utils/functional.py", line 33, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/home/rapolas/temp/mysite/venv/local/lib/python2.7/site-packages/django/core/urlresolvers.py", line 417, in url_patterns
    patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
  File "/home/rapolas/temp/mysite/venv/local/lib/python2.7/site-packages/django/utils/functional.py", line 33, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/home/rapolas/temp/mysite/venv/local/lib/python2.7/site-packages/django/core/urlresolvers.py", line 410, in urlconf_module
    return import_module(self.urlconf_name)
  File "/usr/lib/python2.7/importlib/__init__.py", line 37, in import_module
    __import__(name)
  File "/home/rapolas/temp/mysite/mysite/urls.py", line 20, in <module>
    from myapp import views
  File "/home/rapolas/temp/mysite/myapp/views.py", line 4, in <module>
    from .forms import ReportForm
  File "/home/rapolas/temp/mysite/myapp/forms.py", line 5, in <module>
    class ReportForm(forms.Form):
  File "/home/rapolas/temp/mysite/myapp/forms.py", line 9, in ReportForm
    initial=[item for item in Item.objects.all()])
  File "/home/rapolas/temp/mysite/venv/local/lib/python2.7/site-packages/django/db/models/query.py", line 258, in __iter__
    self._fetch_all()
  File "/home/rapolas/temp/mysite/venv/local/lib/python2.7/site-packages/django/db/models/query.py", line 1074, in _fetch_all
    self._result_cache = list(self.iterator())
  File "/home/rapolas/temp/mysite/venv/local/lib/python2.7/site-packages/django/db/models/query.py", line 52, in __iter__
    results = compiler.execute_sql()
  File "/home/rapolas/temp/mysite/venv/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 852, in execute_sql
    cursor.execute(sql, params)
  File "/home/rapolas/temp/mysite/venv/local/lib/python2.7/site-packages/django/db/backends/utils.py", line 79, in execute
    return super(CursorDebugWrapper, self).execute(sql, params)
  File "/home/rapolas/temp/mysite/venv/local/lib/python2.7/site-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "/home/rapolas/temp/mysite/venv/local/lib/python2.7/site-packages/django/db/utils.py", line 95, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "/home/rapolas/temp/mysite/venv/local/lib/python2.7/site-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "/home/rapolas/temp/mysite/venv/local/lib/python2.7/site-packages/django/db/backends/sqlite3/base.py", line 323, in execute
    return Database.Cursor.execute(self, query, params)
django.db.utils.OperationalError: no such table: myapp_item
(venv)➜  mysite  $

comment:5 by Marten Kenbeek, 8 years ago

File "/home/rapolas/temp/mysite/myapp/forms.py", line 9, in ReportForm
    initial=[item for item in Item.objects.all()])

Like I said, this executes a query when the form is imported. You need to change it to initial=Item.objects.all().

comment:6 by Rapolas K., 8 years ago

Thanks, it works fine with a change. I don't understand though why it was working in 1.8.7 version.

comment:7 by Shai Berger, 8 years ago

https://docs.djangoproject.com/en/1.9/releases/1.9/#urls

Because before 1.9, urls were not imported until the first request came in (and thus, not at all for migrations)

Note: See TracTickets for help on using tickets.
Back to Top