Opened 12 years ago

Closed 12 years ago

Last modified 12 years ago

#17880 closed New feature (duplicate)

"post_save" signal should not be emitted when using manage.py "loaddata"

Reported by: Si Feng Owned by: nobody
Component: Uncategorized Version: 1.3
Severity: Normal Keywords: loaddata, post_save, signal, management commands
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I spent some time on migrating database from MySQL to PostgreSQL. I used "dumpdata" to dump all data from MySQL into json ("pure" data, better than MySQL raw dump and then convert to PostgreSQL, which will cause losing some database specific features). Then I created a new database in PostgreSQL, and "syncdb". I also didn't forget to wipe it out completed by running "python manage.py sqlflush | psql -U myusername mydatabase".

However when I used "loaddata", I always get error (unique key conflict or something). I checked the database and it has nothing. I was confused.

Finally I found that in a few models of mine, I actually used "post_save" signal to create instance after a new User instance was created, like this:

def create_stat(sender, instance, created, **kwargs):
    if created:
        Stat.objects.create(user=instance)

post_save.connect(create_stat, sender=User)

The Stat is like an extension to the User and it has a OneToOneField "user" to the User instance.

By commenting out the above post_save callback, the data was imported correctly into PostgreSQL. Then after resetting sequences, the migration was done.

So the reason is now clear: when "loaddata" loads data from json and creates a User instance, the "post_save" signal will always be emitted, resulting a new Stat instance is created as well. Then when loading the actually Stat data from json, error will occur since there is already a Stat instance for each User.

I'm not sure if using "post_save" signal in my case is a good practice (I just wanted to automatically create some instances when a new user is created. I know I can also put some check code in views and create instances if there is none, but that would look ugly). But I'm thinking perhaps "loaddata" could provide an option to temporarily disable emitting signals when loading data? I mean when someone is "loading" data it usually means the data should be completed "loaded" rather than "running bulk save" which could cause problems by signals/transactions/etc.

Change History (2)

comment:1 by Taylor Mitchell, 12 years ago

Resolution: duplicate
Status: newclosed
Type: UncategorizedNew feature

Thanks for the report. This appears to duplicate the feature request in ticket #8399, so please check that out. There currently exists a workaround using the "raw" argument to pre/post_save.

Here are some links that might help:

comment:2 by Si Feng, 12 years ago

Great, thanks for the links. The "raw" argument check works.

Note: See TracTickets for help on using tickets.
Back to Top