Opened 14 years ago

Closed 13 years ago

Last modified 13 years ago

#13818 closed (invalid)

Check Child IDs before creating parent IDs

Reported by: Paul Bailey Owned by: nobody
Component: Database layer (models, ORM) Version: 1.2
Severity: Keywords: sprintdec2010
Cc: sghael@… Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

When saving new models that are inherited Django currently creates the parent model, gets a primary key and then uses this primary key in the child model to relate it to the parent. This is 99.9% of the time fine but we had some data inconsistency issues where the auto incremented parent id was already used in the child table. Thus creating the parent succeeds but creating the child fails. So it would be nice if Django when creating the parent first checked if the primary key was already being used in the child tables, and if it is being used to auto increment until a valid ID is found.

I've included below our sample models and the traceback we received when this happens.

class Content(models.Model):
  headline                  = models.CharField(max_length=255, blank=False)
  
  def get_type(self):
    try:
      if self.newsbrief:
        return 'News Briefs'
    except DoesNotExist:
      try:
        if self.industryarticle:
          return 'Industry Articles'
      except DoesNotExist:
        try:
          if self.industrypaper:
            return 'Industry Papers'
        except DoesNotExist:
          return 'Case Studies'
  
  def __unicode__(self):
    return self.headline

class NewsBrief(Content):
  kicker                    = models.CharField(max_length=4096, blank=True)
  slug                      = models.SlugField(unique=True, max_length=128, help_text=_("the slug dictates the permanent url of this content."))
  date                      = models.DateTimeField(help_text=_("date/time that appears on article"))
  byline                    = models.CharField(max_length=4096, blank=True)
  body_copy                 = models.TextField(blank=True, null=True)
  file_name                 = models.CharField(max_length=256, blank=True)
  file_upload               = models.FileField(upload_to=file_path, help_text=("Attach a file"), blank=True) # pdf
  #related_products          = models.ManyToManyField(Product, blank=True, null=True)
  tags                      = models.ManyToManyField(Tag, blank=True, null=True)
Request Method: POST
Request URL: http://localhost:8000/admin/content/industryarticle/add/
Django Version: 1.2
Python Version: 2.6.4
Installed Applications:
['django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.sites',
 'django.contrib.messages',
 'django.contrib.admin',
 'pagination',
 'south',
 'arnco.main',
 'arnco.product',
 'arnco.presence',
 'arnco.content',
 'arnco.order',
 'arnco.tag']
Installed Middleware:
('django.middleware.common.CommonMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'pagination.middleware.PaginationMiddleware')


Traceback:
File "/Users/sghael/virtualenvs/arnco/lib/python2.6/site-packages/django/core/handlers/base.py" in get_response
  100.                     response = callback(request, *callback_args, **callback_kwargs)
File "/Users/sghael/virtualenvs/arnco/lib/python2.6/site-packages/django/contrib/admin/options.py" in wrapper
  239.                 return self.admin_site.admin_view(view)(*args, **kwargs)
File "/Users/sghael/virtualenvs/arnco/lib/python2.6/site-packages/django/utils/decorators.py" in _wrapped_view
  76.                     response = view_func(request, *args, **kwargs)
File "/Users/sghael/virtualenvs/arnco/lib/python2.6/site-packages/django/views/decorators/cache.py" in _wrapped_view_func
  69.         response = view_func(request, *args, **kwargs)
File "/Users/sghael/virtualenvs/arnco/lib/python2.6/site-packages/django/contrib/admin/sites.py" in inner
  190.             return view(request, *args, **kwargs)
File "/Users/sghael/virtualenvs/arnco/lib/python2.6/site-packages/django/utils/decorators.py" in _wrapper
  21.             return decorator(bound_func)(*args, **kwargs)
File "/Users/sghael/virtualenvs/arnco/lib/python2.6/site-packages/django/utils/decorators.py" in _wrapped_view
  76.                     response = view_func(request, *args, **kwargs)
File "/Users/sghael/virtualenvs/arnco/lib/python2.6/site-packages/django/utils/decorators.py" in bound_func
  17.                 return func(self, *args2, **kwargs2)
File "/Users/sghael/virtualenvs/arnco/lib/python2.6/site-packages/django/db/transaction.py" in _commit_on_success
  299.                     res = func(*args, **kw)
File "/Users/sghael/virtualenvs/arnco/lib/python2.6/site-packages/django/contrib/admin/options.py" in add_view
  795.                 self.save_model(request, new_object, form, change=False)
File "/Users/sghael/virtualenvs/arnco/lib/python2.6/site-packages/django/contrib/admin/options.py" in save_model
  597.         obj.save()
File "/Users/sghael/Documents/MWM/arnco/../arnco/content/models.py" in save
  53.     super(IndustryArticle, self).save()
File "/Users/sghael/virtualenvs/arnco/lib/python2.6/site-packages/django/db/models/base.py" in save
  435.         self.save_base(using=using, force_insert=force_insert, force_update=force_update)
File "/Users/sghael/virtualenvs/arnco/lib/python2.6/site-packages/django/db/models/base.py" in save_base
  479.                 self.save_base(cls=parent, origin=org, using=using)
File "/Users/sghael/virtualenvs/arnco/lib/python2.6/site-packages/django/db/models/base.py" in save_base
  528.                     result = manager._insert(values, return_id=update_pk, using=using)
File "/Users/sghael/virtualenvs/arnco/lib/python2.6/site-packages/django/db/models/manager.py" in _insert
  195.         return insert_query(self.model, values, **kwargs)
File "/Users/sghael/virtualenvs/arnco/lib/python2.6/site-packages/django/db/models/query.py" in insert_query
  1479.     return query.get_compiler(using=using).execute_sql(return_id)
File "/Users/sghael/virtualenvs/arnco/lib/python2.6/site-packages/django/db/models/sql/compiler.py" in execute_sql
  783.         cursor = super(SQLInsertCompiler, self).execute_sql(None)
File "/Users/sghael/virtualenvs/arnco/lib/python2.6/site-packages/django/db/models/sql/compiler.py" in execute_sql
  727.         cursor.execute(sql, params)
File "/Users/sghael/virtualenvs/arnco/lib/python2.6/site-packages/django/db/backends/util.py" in execute
  15.             return self.cursor.execute(sql, params)
File "/Users/sghael/virtualenvs/arnco/lib/python2.6/site-packages/django/db/backends/mysql/base.py" in execute
  86.             return self.cursor.execute(query, args)
File "build/bdist.macosx-10.6-i386/egg/MySQLdb/cursors.py" in execute
  175.         if not self._defer_warnings: self._warning_check()
File "build/bdist.macosx-10.6-i386/egg/MySQLdb/cursors.py" in _warning_check
  89.                     warn(w[-1], self.Warning, 3)

Exception Type: Warning at /admin/content/industryarticle/add/
Exception Value: Field 'content_pk' doesn't have a default value

Change History (2)

comment:1 by Thomas Ashelford, 13 years ago

Keywords: sprintdec10 added
Resolution: invalid
Status: newclosed

There's not enough detail here to reproduce the problem IMHO. We simply don't know what state the dB was in when this error occurred. Specifically we don't know how "the auto incremented parent id was already used in the child table". If this state was created via the ORM, then there is a genuine problem, but we'd need to know how you managed to do that before moving forward.

I'm also not convinced that the stacktrace is complaining about the pk being already in use. You may find some clues in #3997 "Missing default value causes exception on save"

comment:2 by Thomas Ashelford, 13 years ago

Keywords: sprintdec2010 added; sprintdec10 removed
Note: See TracTickets for help on using tickets.
Back to Top