I'm using Django 1.6 and I use South to handle migrations.
In most of my application I used to have initial_data.json
files. I converted them to be loaded with migrations rather than automatically by Django (as this is recommended in the documentation)
I was using version 0.8.2 of South when I ran into a weird behavior / bug where loading fixtures is done according to the model code and not the state of the migration. I saw that the newest version (0.8.4) has since added some bug fixes related to loaddata
, so I upgraded to it.
Now I get the following error on all the migration that load fixtures:
UserWarning: No fixture named 'X' found.
When I use Django's loaddata
it works fine. Any ideas on how to solve this?
South simply patches syncdb to skip the fixture loading for models with migrations, and actually loads them after the final migration for an app has been run.
Loading initial_data does not require you do actually do something, but place the fixtures in the correct place as explained in Django's documentation.
To quote the docs:
By default, Django looks in the fixtures directory inside each app for fixtures. You can set the FIXTURE_DIRS setting to a list of additional directories where Django should look.
This means that if you have an app called "myapp", you'd create a "fixtures" dir inside it and place the json there, e.g.: myproject/myapp/fixtures
.
Django 1.7 introduced built-in migrations. These have an interface similar to South; management commands to create migrations makemigrations
, run them migrate
, and others.
However, initial_data
fixtures are no longer auto-loaded on syncdb run; unless it is an existing app, and has no migrations. This is mentioned in the release notes.
The docs now recomend to create a datamigration
to handle fixture loading. Luckily, this is pretty easy to do, here's how I usually do it:
$ python manage.py makemigrations --empty myapp
If you had only the initial migration, you end up with these files (note that I renamed migration 0002 for clarity):
myapp/
├── __init__.py
├── fixtures
│ └── my_initial_data.json
└── migrations
├── 0001_initial.py
├── 0002_load_fixture.py
└── __init__.py
0002_load_fixture.py
to run loaddata# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations
from django.core.management import call_command
def load_my_initial_data(apps, schema_editor):
call_command("loaddata", "my_initial_data.json")
class Migration(migrations.Migration):
dependencies = [
('myapp', '0001_initial'),
]
operations = [
migrations.RunPython(load_my_initial_data),
]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With