#13974: saving object with multi-table inheritance is not transactional by 
default
------------------------------------------+---------------------------------
 Reporter:  ccurvey                       |       Owner:  nobody    
   Status:  new                           |   Milestone:            
Component:  Database layer (models, ORM)  |     Version:  1.2       
 Keywords:                                |       Stage:  Unreviewed
Has_patch:  0                             |  
------------------------------------------+---------------------------------
 if you are using multi-table inheritance, and there is some problem
 writing to one of the tables, some tables are updated, and some are not.

 (MySQL 5.x on Ubuntu, Django 1.2rc 1 on Windows)

 1) Set up a new project with database settings like so:

 {{{
 DATABASES = {
     'default': {
         'ENGINE': 'django.db.backends.mysql',
         'NAME': 'mydb',
         'USER': 'myuser',
         'PASSWORD': 'mypassword'
         'HOST': 'myhost',
         'PORT': '',
         'OPTIONS' : {
             'init_command' : 'set storage_engine=INNODB',
             },

     }
 }
 }}}

 2) Now set up some models that use inheritance:

 {{{
 from django.db import models

 # Create your models here.

 class Foo(models.Model):
     a = models.IntegerField()

 class Bar(Foo):
     b = models.IntegerField()

 }}}

 3) Now create a script that does something obviously wrong.

 {{{
 import sys
 sys.path.append(r"C:\users\ccurvey")
 sys.path.append(r"C:\users\ccurvey\testme")
 sys.path.append(r"C:\users\ccurvey\testme\foobar")

 import os
 os.environ["DJANGO_SETTINGS_MODULE"] = 'settings'

 from foobar.models import Bar

 # try testing something that is clearly wrong.
 bar = Bar(a=1, b="A")

 # this is going to throw a ValueError
 bar.save()

 }}}

 4) Now go look at the underlying tables in MySQL:

 {{{
 mysql> select * from foobar_foo;
 +----+---+
 | id | a |
 +----+---+
 |  1 | 1 |
 +----+---+
 1 row in set (0.00 sec)

 mysql> select * from foobar_bar;
 Empty set (0.00 sec)

 }}}

 The workaround is to add @commit_on_success and a save() method to Bar,
 like so, but it seems (to me) like this should be unncessary.

 {{{
 from django.db.transaction import commit_on_success


 class Bar(Foo):
     b = models.IntegerField()

     @commit_on_success
     def save(self):
         super(Bar, self).save()

 }}}

-- 
Ticket URL: <http://code.djangoproject.com/ticket/13974>
Django <http://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en.

Reply via email to