DoRivard
DoRivard

Reputation: 832

Django Model SyncDB fail on the choices attribute due to a DB error

Here is a little error I get when trying to use syncdb on my django project.

Error:

Traceback (most recent call last):
  File "manage.py", line 11, in <module>
    execute_manager(settings)
  File "/usr/local/lib/python2.6/dist-packages/django/core/management/__init__.py", line 438, in execute_manager
    utility.execute()
  File "/usr/local/lib/python2.6/dist-packages/django/core/management/__init__.py", line 379, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/local/lib/python2.6/dist-packages/django/core/management/base.py", line 191, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "/usr/local/lib/python2.6/dist-packages/django/core/management/base.py", line 219, in execute
    self.validate()
  File "/usr/local/lib/python2.6/dist-packages/django/core/management/base.py", line 249, in validate
    num_errors = get_validation_errors(s, app)
  File "/usr/local/lib/python2.6/dist-packages/django/core/management/validation.py", line 28, in get_validation_errors
    for (app_name, error) in get_app_errors().items():
  File "/usr/local/lib/python2.6/dist-packages/django/db/models/loading.py", line 146, in get_app_errors
    self._populate()
  File "/usr/local/lib/python2.6/dist-packages/django/db/models/loading.py", line 61, in _populate
    self.load_app(app_name, True)
  File "/usr/local/lib/python2.6/dist-packages/django/db/models/loading.py", line 78, in load_app
    models = import_module('.models', app_name)
  File "/usr/local/lib/python2.6/dist-packages/django/utils/importlib.py", line 35, in import_module
    __import__(name)
  File "/opt/admin-site/adminsite/cfadmin/models.py", line 111, in <module>
    class RequestLog(models.Model):
  File "/opt/admin-site/adminsite/cfadmin/models.py", line 117, in RequestLog
    profile     = models.PositiveIntegerField(null=True,blank=True, choices=get_profiles()) # It cannot be a foreign key this is not on the same DB 
  File "/opt/admin-site/adminsite/cfadmin/models.py", line 107, in get_profiles
    cache.set('profiles_choices', profiles_choices, 3600)
  File "/usr/local/lib/python2.6/dist-packages/django/core/cache/backends/locmem.py", line 83, in set
    self._set(key, pickle.dumps(value), timeout)
  File "/usr/lib/python2.6/copy_reg.py", line 84, in _reduce_ex
    dict = getstate()
  File "/usr/local/lib/python2.6/dist-packages/django/db/models/query.py", line 61, in __getstate__
    len(self)
  File "/usr/local/lib/python2.6/dist-packages/django/db/models/query.py", line 81, in __len__
    self._result_cache = list(self.iterator())
  File "/usr/local/lib/python2.6/dist-packages/django/db/models/query.py", line 947, in iterator
    for row in self.query.get_compiler(self.db).results_iter():
  File "/usr/local/lib/python2.6/dist-packages/django/db/models/sql/compiler.py", line 672, in results_iter
    for rows in self.execute_sql(MULTI):
  File "/usr/local/lib/python2.6/dist-packages/django/db/models/sql/compiler.py", line 727, in execute_sql
    cursor.execute(sql, params)
  File "/usr/local/lib/python2.6/dist-packages/django/db/backends/postgresql_psycopg2/base.py", line 44, in execute
    return self.cursor.execute(query, args)
django.db.utils.DatabaseError: relation "cfadmin_profile" does not exist
LINE 1: ...dmin_profile"."id", "cfadmin_profile"."name" FROM "cfadmin_p...

The models:

class Profile(models.Model):
    name        = models.CharField(max_length=256)
    categories  = models.ManyToManyField(Category)

    def __unicode__(self):
        return self.name

    class Meta():
        ordering = ["name"]

def get_profiles():
    profiles_choices = cache.get('profiles_choices')
    if profiles_choices == None:
        try:
            profiles_choices = Profile.objects.values_list('id','name')
            cache.set('profiles_choices', profiles_choices, 3600)
        except:
            logging.info("Failed to retrieve the profile choices.")
            pass

    return profiles_choices


class Log(models.Model):
    domain      = models.CharField(max_length=512)
    profile     = models.PositiveIntegerField(null=True,blank=True, choices=get_profiles()) # this is where I get the error on Syncdb


    def __unicode__(self):
        return self.domain

    class Meta():
        ordering = ["domain"]

So if I am syncing a new project I will get the error that I mentioned earlier. If I remove the call to my function get_profiles() in the model choices, it will synchronize with no error.

But I don't understand why I'm still getting the error even do I put a try catch within the function. So in case of an error I would expect that it continues but instead it's completely aborting the syncdb.

Is there anyway to achieve what I'm trying to without removing the function and the put it back?

Thank you!

Upvotes: 0

Views: 554

Answers (2)

Daniel Roseman
Daniel Roseman

Reputation: 599846

This is not the way to get choices for a model. Even if you fix your circular dependency problem, you will still have the issue that the get_choices() function will be called when the server process starts, and won't change in the meantime. Unlike default, I don't believe choices can be a callable.

Upvotes: 2

Sergey Golovchenko
Sergey Golovchenko

Reputation: 18671

From the django doc " ... if you find yourself hacking choices to be dynamic, you're probably better off using a proper database table with a ForeignKey. choices is meant for static data that doesn't change much, if ever."

So you are probably better of changing your profile field in the Log model:

profile = models.ForeignKey(Profile, null=True,blank=True)

Upvotes: 2

Related Questions