Code

Opened 4 years ago

Closed 4 years ago

Last modified 4 years ago

#14535 closed (invalid)

Model.objects.all() causing ImportError in Django 1.2.3 in stand-alone script

Reported by: benedikt Owned by: nobody
Component: Database layer (models, ORM) Version: 1.2
Severity: Keywords: ImportError, objects.all, maverick
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

After upgrading Ubuntu from Lucid to Maverick I have stumbled upon what seems to be a bug. Consider this stand-alone script that talks to a Django application, where Source is a Model object. Feedparser is a python module that parses RSS feeds (www.feedparser.org).

>>> from feedparser import feedparser
>>> from django.core.management import setup_environ
>>> import os, sys
>>> sys.path.append('/home/benedikt/repos/frettaveita/')
>>> os.environ['DJANGO_SETTINGS_MODULE'] = 'settings' 
>>> import settings        
>>> from newsaggregator.models import Source
>>> mbl = Source.objects.get(name = 'mbl-innlent')

The normal behavior would be that mbl now is the Source object with the name 'mbl-innlent'. This however doesn't happen, but instead a ImportError is thrown and a rather large Traceback is printed.

>>> mbl = Source.objects.get(name = 'mbl-innlent')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/pymodules/python2.6/django/db/models/manager.py", line 132, in get
    return self.get_query_set().get(*args, **kwargs)
  File "/usr/lib/pymodules/python2.6/django/db/models/query.py", line 333, in get
    clone = self.filter(*args, **kwargs)
  File "/usr/lib/pymodules/python2.6/django/db/models/query.py", line 550, in filter
    return self._filter_or_exclude(False, *args, **kwargs)
  File "/usr/lib/pymodules/python2.6/django/db/models/query.py", line 568, in _filter_or_exclude
    clone.query.add_q(Q(*args, **kwargs))
  File "/usr/lib/pymodules/python2.6/django/db/models/sql/query.py", line 1128, in add_q
    can_reuse=used_aliases)
  File "/usr/lib/pymodules/python2.6/django/db/models/sql/query.py", line 1026, in add_filter
    negate=negate, process_extras=process_extras)
  File "/usr/lib/pymodules/python2.6/django/db/models/sql/query.py", line 1179, in setup_joins
    field, model, direct, m2m = opts.get_field_by_name(name)
  File "/usr/lib/pymodules/python2.6/django/db/models/options.py", line 291, in get_field_by_name
    cache = self.init_name_map()
  File "/usr/lib/pymodules/python2.6/django/db/models/options.py", line 321, in init_name_map
    for f, model in self.get_all_related_m2m_objects_with_model():
  File "/usr/lib/pymodules/python2.6/django/db/models/options.py", line 396, in get_all_related_m2m_objects_with_model
    cache = self._fill_related_many_to_many_cache()
  File "/usr/lib/pymodules/python2.6/django/db/models/options.py", line 410, in _fill_related_many_to_many_cache
    for klass in get_models():
  File "/usr/lib/pymodules/python2.6/django/db/models/loading.py", line 167, in get_models
    self._populate()
  File "/usr/lib/pymodules/python2.6/django/db/models/loading.py", line 61, in _populate
    self.load_app(app_name, True)
  File "/usr/lib/pymodules/python2.6/django/db/models/loading.py", line 76, in load_app
    app_module = import_module(app_name)
  File "/usr/lib/pymodules/python2.6/django/utils/importlib.py", line 35, in import_module
    __import__(name)
ImportError: No module named frettaveita.newsaggregator
>>> 

If, however, we try the same piece of code a second time, right after the failed attempt it works, such as

>>> mbl = Source.objects.get(name = 'mbl-innlent')
>>> mbl
<Source: mbl-innlent>
>>> 

This was also the behavior in the Django 1.1.1, supplied with Ubuntu Lucid. The workaround is simple but ugly

try:
    mbl = Source.objects.get(name='mbl-innlent')
except ImportError:
    mbl = Source.objects.get(name='mbl-innlent')

since it will work in the second try if the first one fails. I have not been able to pinpoint the bug yet or patch it. However, I am not sure if this is a regression or if this is indeed the expected behavior.

Attachments (0)

Change History (3)

comment:1 Changed 4 years ago by sayane

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

Are you sure, that you have good pythonpath?

Instead of:

>>> sys.path.append('/home/benedikt/repos/frettaveita/')

try:

>>> sys.path.append('/home/benedikt/repos/')

comment:2 follow-up: Changed 4 years ago by benedikt

  • Resolution set to invalid
  • Status changed from new to closed

Thank you, this works and is on par with own conclusion that django/db/models/loading.py is now importing frettaveita.newsaggregator (that is, <django project name>.<module name>), instead of just <module name> which seems to have been the behavior in the previous django version.

I still don't understand why the second attempt is always successful.

comment:3 in reply to: ↑ 2 Changed 4 years ago by kmtracey

Replying to benedikt:

This behavior may be due to the fix for #11696, which causes errors that used to be (incorrectly) swallowed during app model loading to be raised instead. I'm guessing you have the app listed including the project name in INSTALLED_APPS, in which case you should have the parent of the project directory included in the Python path. As for why it works the 2nd time, I'm not really sure. It seems the app loading code somehow considers the app loaded even after the error, which does not seem quite right...there may be a bug there, though I'm not sure.

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.