Search code examples
pythondjangodjango-south

South appears to be loading initial_data.json twice


I've been working with South on a new Django project.

I've just added a new model Client, and I'd like to make ensure that any of the tests that get run, or any new database setups, always get populated with an instance of Client, so I've added a new instance into the project's initial_data.json.

Now whenever I run the tests, or populate a new database, it looks like initial_data.json is being loaded twice - once after the tables are first created. (which fails with a traceback). and a second time, after the migrations have been applied. (which succeeds just fine)

For instance, running manage.py syncdb --migrate --noinput gives me the following output:

Syncing...
Creating tables ...
<snip>
Installing custom SQL ...
Installing indexes ...
Problem installing fixture 'initial_data.json': Traceback (most recent call last):
  File ".../django/core/management/commands/loaddata.py", line 174, in handle
    obj.save(using=using)
  File ".../django/core/serializers/base.py", line 165, in save
    models.Model.save_base(self.object, using=using, raw=True)
  File ".../django/db/models/base.py", line 522, in save_base
    manager.using(using).filter(pk=pk_val).exists())):
  File ".../django/db/models/query.py", line 496, in exists
    return self.query.has_results(using=self.db)
  File ".../django/db/models/sql/query.py", line 424, in has_results
    return bool(compiler.execute_sql(SINGLE))
  File ".../django/db/models/sql/compiler.py", line 735, in execute_sql
    cursor.execute(sql, params)
  File ".../django/db/backends/util.py", line 34, in execute
    return self.cursor.execute(sql, params)
  File ".../django/db/backends/sqlite3/base.py", line 234, in execute
    return Database.Cursor.execute(self, query, params)
DatabaseError: no such table: core_client 
Migrating...
Running migrations for core:
<snip>
 - Loading initial data for assetcloud.
Installed 5 object(s) from 1 fixture(s)

Or, if I run manage.py test SouthProblems on the following test:

class SouthProblems(TestCase):
    def test_south_problems(self):
        print Client.objects.all()

I'll get this output:

Creating test database for alias 'default'...
Problem installing fixture 'initial_data.json': Traceback (most recent call last):
<snip, as before>
DatabaseError: no such table: core_client

[<Client: example>]
.
----------------------------------------------------------------------
Ran 1 test in 0.013s

OK

In both cases the initial data does appear to have been successfully created, but I'm getting unnecessary tracebacks.

I'm wondering if I'm not quite using South correctly wrt. initial data fixtures?

I also tracked this ticket down: http://south.aeracode.org/ticket/372 which sounds like what I'm seeing, but that was 18 months ago, and the ticket is marked as fixed.

I'm running Django 1.3, and South 0.7.3

EDIT:

I've also seen this: http://south.aeracode.org/docs/commands.html#initial-data-and-post-syncdb although I'm not totally sure from the documentation notes if I should expect to see South attempting to load the fixtures before any migrations have been applied.

There's this https://groups.google.com/d/topic/south-users/PWpQn61UDmI/discussion, which suggests that using initial_data might not be a sensible thing to do with South, but I'm somewhat surprised I've not seen the same thing mentioned elsewhere?... (I've posted a question to the list there, too, but it's awaiting moderation)


Solution

  • The recommended solution is not to use initial data fixtures with South at all, but to call loaddata from inside a migration instead:

    See this discussion on Google Groups - link