views:

57

answers:

1

I'm really confused by some errors I'm getting as I'm trying to put an App into production. Everything works fine on the development machine, but I can't syncdb or enter the Django shell on the Production server. I'm getting an error when forum.models.py is attempts to import forum.managers.py because the models aren't in the namespace yet.

I think it could be a PYTHONPATH issue, but it has a weird Chicken or Egg aspect to it. I don't understand why TagManager is not in the NameSpace.
TagManager is imported via:
from forum.managers import *
Which is executed before the the TagManager class is called.

$ python2.5 manage.py syncdb
Traceback (most recent call last):
File "manage.py", line 11, in
execute_manager(settings)
File "/home/app_name/webapps/app_name/lib/python2.5/django/core/management/init.py", line 362, in execute_manager
utility.execute()
File "/home/app_name/webapps/app_name/lib/python2.5/django/core/management/init.py", line 303, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/app_name/webapps/app_name/lib/python2.5/django/core/management/base.py", line 195, in run_from_argv
self.execute(*args, **options.dict)
File "/home/app_name/webapps/app_name/lib/python2.5/django/core/management/base.py", line 221, in execute
self.validate()
File "/home/app_name/webapps/app_name/lib/python2.5/django/core/management/base.py", line 249, in validate
num_errors = get_validation_errors(s, app)
File "/home/app_name/webapps/app_name/lib/python2.5/django/core/management/validation.py", line 28, in get_validation_errors
for (app_name, error) in get_app_errors().items():
File "/home/app_name/webapps/app_name/lib/python2.5/django/db/models/loading.py", line 131, in get_app_errors
self._populate()
File "/home/app_name/webapps/app_name/lib/python2.5/django/db/models/loading.py", line 58, in _populate
self.load_app(app_name, True)
File "/home/app_name/webapps/app_name/lib/python2.5/django/db/models/loading.py", line 74, in load_app
models = import_module('.models', app_name)
File "/home/app_name/webapps/app_name/lib/python2.5/django/utils/importlib.py", line 35, in import_module
import(name)
File "/home/app_name/webapps/app_name/django_app/../django_app/forum/models.py", line 18, in
from forum.managers import *
File "/home/app_name/webapps/app_name/django_app/forum/managers.py", line 6, in
from forum.models import *
File "/home/app_name/webapps/app_name/django_app/../django_app/forum/models.py", line 43, in
class Tag(models.Model):
File "/home/app_name/webapps/app_name/django_app/../django_app/forum/models.py", line 53, in Tag
objects = TagManager()
NameError: name 'TagManager' is not defined

Python 2.5.4 (r254:67916, Aug  5 2009, 12:42:40)   
[GCC 4.1.2 20080704 (Red Hat 4.1.2-44)] on linux2  
Type "help", "copyright", "credits" or "license" for more information.  
>>> import os  
>>> os.environ['DJANGO_SETTINGS_MODULE'] = 'django_app.settings'  
>>>   
>>> import sys  
>>> import pprint  
>>> pprint.pprint(sys.path)  
['',  
 '/home/app_name/webapps/app_name/lib/python2.5',  
 '/home/app_name/lib/python2.5/markdown2-1.0.1.16-py2.5.egg',  
 '/home/app_name/lib/python2.5/html5lib-0.11.1-py2.5.egg',  
 '/home/app_name/lib/python2.5',  
 '/usr/local/lib/python25.zip',  
 '/usr/local/lib/python2.5',  
 '/usr/local/lib/python2.5/plat-linux2',  
 '/usr/local/lib/python2.5/lib-tk',  
 '/usr/local/lib/python2.5/lib-dynload',  
 '/usr/local/lib/python2.5/site-packages',  
 '/usr/local/lib/python2.5/site-packages/PIL']  
>>> sys.path = ['/home/app_name/webapps/app_name/django_app','/home/app_name/webapps/app_name','/home/app_name/webapps/app_name/lib/python2.5'] + sys.path  
>>> pprint.pprint(sys.path)['/home/app_name/webapps/app_name/django_app',  
 '/home/app_name/webapps/app_name',  
 '/home/app_name/webapps/app_name/lib/python2.5',  
 '',  
 '/home/app_name/webapps/app_name/lib/python2.5',  
 '/home/app_name/lib/python2.5/markdown2-1.0.1.16-py2.5.egg',  
 '/home/app_name/lib/python2.5/html5lib-0.11.1-py2.5.egg',  
 '/home/app_name/lib/python2.5',  
 '/usr/local/lib/python25.zip',  
 '/usr/local/lib/python2.5',  
 '/usr/local/lib/python2.5/plat-linux2',  
 '/usr/local/lib/python2.5/lib-tk',  
 '/usr/local/lib/python2.5/lib-dynload',  
 '/usr/local/lib/python2.5/site-packages',  
 '/usr/local/lib/python2.5/site-packages/PIL']  
>>> from forum.managers import *  
Traceback (most recent call last):  
  File "<stdin>", line 1, in <module>  
  File "/home/app_name/webapps/app_name/django_app/forum/managers.py", line 6, in <module>  
    from forum.models import *  
  File "/home/app_name/webapps/app_name/django_app/../django_app/forum/models.py", line 43, in <module>  
    class Tag(models.Model):  
  File "/home/app_name/webapps/app_name/django_app/../django_app/forum/models.py", line 53, in Tag  
    objects = TagManager()  
NameError: name 'TagManager' is not defined  
>>> from forum.models import *  
>>> from forum.managers import *  
>>> objects = TagManager()  
>>> objects  
<forum.managers.TagManager object at 0x9b9fdac>  
>>>   
+1  A: 

Your problem is you do:

from forum.managers import * (at line 18 models.py) from forum.models import * (at line 6 managers.py)

How can that ever work? Try flattening this out (do the imports by hand copying and pasting into a new file) and you'll see why, by the time it executes the line "objects = TagManager()" it cannot possibly have executed the part of the managers module where TagManager is defined, unless it was defined before line 18.

Some general tips:

  1. Avoid the * imports whenever possible (it makes python programs harder to read if nothing else)
  2. If you have circular imports like that, try to break them up. Often in one module you can move the import into a function call, or you can refactor some elements into a third module that both can import from. You can also try moving the import lower in the module, which sometimes works.
Eloff
I changed the import to explicitly create the Managers namespace.Eveything seems to work now, but I'd like more clarification on why the wildcard * looped and the explicit names do not.
BryanWheelock