Load Multiple Fixtures at Once
Asked Answered
H

12

35

Is there anyway to load one fixture and have it load multiple fixtures?

I'd ideally like to type:

python manage.py loaddata all_fixtures

And have that load all of the data instead of having to type everything. Is this possible?

Hogg answered 8/2, 2010 at 21:39 Comment(1)
can you give us an example of what your fixture directory looks like, more specifically what files are in it?Chimene
O
49

Using $ python manage.py loaddata myfixtures/*.json would work as Bash will substitute the wildcard to a list of matching filenames.

Oiler answered 9/2, 2010 at 12:50 Comment(4)
On Mac OS X I get: "UserWarning: No fixture named '*' found."Hardboard
Is there anything can be done to do it in particular sequence ?Syndrome
It is working. $ python manage.py loaddata folder_name/*.jsonIbsen
This solved the issue on mac: python manage.py loaddata $(find path/to/fixtures -type f -name '*.json') Openandshut
S
28

I have multiple apps on the project directory and have each app with its 'fixtures' directory. So using some bash I can do:

python3 manage.py loaddata */fixtures/*.json

And that expands all of the json files inside of the fixtures directory on each app in my project. You can test it by simply doing:

ls */fixtures/*.json

Sporocyte answered 14/5, 2015 at 13:39 Comment(2)
Works for macOSApatetic
This works, however, in my case, I had to make sure the fixtures were loaded in a particular order (dependencies). So, I loaded them one file after the other.Dinosaurian
G
15

This thread shows up among the first results with a Google search "load data from all fixtures" and doesn't mention what IMO is the correct solution for this, ie the solution that allows you to load any fixtures you want without any wildcard tricks nor a single modification of the settings.py file (I also used to do it this way)

Just make your apps' fixtures directories flat (and not the usual Django scheme that e.g. goes app_name/templates/app_name/mytemplate.html), ie app_name/fixtures/myfixture.[json, yaml, xml]

Here's what the django doc says :

For example:

django-admin loaddata foo/bar/mydata.json

would search /fixtures/foo/bar/mydata.json for each installed application, /foo/bar/mydata.json for each directory in FIXTURE_DIRS, and the literal path foo/bar/mydata.json.

What that means is that if you have a fixtures/myfixture.json in all your app directories, you just have to run

./manage.py loaddata myfixture

to load all the fixtures that are located there within your project ... And that's it ! You can even restrict what apps you load fixtures from by using --app or --exclude arguments.

I'll mention that I use my fixtures only to populate my database while doing some development so I don't mind having a flat structure in my 'fixtures' directories ... But even if you use your fixtures for tests it seems like having a flat structure is the Django-esque way to go, and as that answer suggests, you would reference the fixture from a specific app by just writing something like :

class MyTestCase(TestCase):
    fixtures = ['app_name/fixtures/myfixture.json']
Governorship answered 16/10, 2017 at 9:6 Comment(0)
B
13

Why not create a Makefile that pulls in all your fixtures? eg something like:

load_all_fixtures: 
    ./manage.py loaddata path/to/fixtures/foo.json
    ./manage.py loaddata path/to/fixtures/bar.json
    ./manage.py loaddata path/to/fixtures/baz.json

And then at the shell prompt, run

make load_all_fixtures

(This kind of approach is also good for executing unit tests for certain apps only and ignoring others, if need be)

Bergess answered 9/2, 2010 at 14:38 Comment(2)
The snippet above is what you'd need in your MakefileBergess
make: Nothing to be done for 'load_all_fixtures'. Got this errorLunisolar
R
5

My command is this, simple. (django 1.6)

python manage.py loaddata a.json b.json c.json
Rustie answered 20/6, 2014 at 9:48 Comment(1)
This is the easiest solution. python manage.py loaddata armor_fixture enemies_fixture player_fixture room_fixture roomgen_fixture weapon_fixture worked for meGallows
P
4

If you want to have this work on linux and windows you simply could use this for loading all your json-Fixtures:

import os
files = os.listdir('path/to/my/fixtures')

def loaddata(file):
    if os.path.splitext(file)[1] == '.json' and file != 'initial_data.json':
        print file
        os.system("python manage.py loaddata %s" % file)

map(loaddata, files)
Pointenoire answered 25/2, 2012 at 10:36 Comment(0)
G
3

Works for me with Django-admin version 3.1.4

python manage.py loaddata json_file_1 json_file_2

My folder structure is like this -

app_name_1
├──fixtures
├────json_file_1.json
├────json_file_2.json
app_name_2
├──fixtures
├────json_file_3.json
Goglet answered 25/12, 2020 at 11:21 Comment(0)
S
1

Manage.py loaddata will look automatically in certain places, so if you name your fixtures the same in each app, or put all your fixtures in the same folder it can be easy to load them all. If you have many different fixtures, and need a more complex naming schema, you can easily load all your fixtures using find with -exec

find . -name "*.json" -exec manage.py loaddata {} \;

As I state in this [question][2], I also have this in a fabfile. EDIT: use python manage.py if manage.py is not in your VE path.

Spindle answered 31/5, 2011 at 11:7 Comment(0)
F
1

If your fixtures are located into the same folder, you can simply ls and xargs: ls myfolder | xargs django-admin loaddata.

Example with this structure:

$ tree fixtures/
root_dir/fixtures/
├── 1_users.json
├── 2_articles.json
└── 3_addresses.json
$ ls -d fixtures/* | xargs django-admin loaddata 

would do the same as:

$ django-admin loaddata 1_users.json
$ django-admin loaddata 2_articles.json
$ django-admin loaddata 3_addresses.json
Freyah answered 23/3, 2020 at 14:17 Comment(1)
I think the sequence number is vital if we need the users.id to fill in the articles or address. thx!Mcconnell
G
0

After doing a bit of searching, I ended up writing this script. It searches through all directories named "fixtures" for .json files and runs a "python manage.py loaddata {fixture_name}.json". Sometimes ordering matters for foreign key constraints, so it leaves a fixture in the queue if the constraint cannot be resolved.

(Note: It requires the pip package simple_terminal that I wrote. And I set it up to be run by 'python manage.py runscript ', which requires django-extensions.)

# load_fixture.py
#
# A script that searches for all .json files in fixtures directories
# and loads them into the working database. This is meant to be run after
# dropping and recreating a database then running migrations.
#
# Usage: python manage.py runscript load_fixtures

from simple_terminal import Terminal

from django.core.management import call_command
from django.db.utils import IntegrityError


def load_fixture(fixture_location):
    # runs command: python manage.py loaddata <fixture_location>
    call_command('loaddata', fixture_location)


def run():
    with Terminal() as t:
        # get all .json files in a fixtures directory
        fixture_locations = t.command(
            'find . -name *.json | grep fixtures | grep -v env')

    while fixture_locations:
        # check that every iteration imports are occuring
        errors = []
        length_before = len(fixture_locations)

        for fl in fixture_locations:
            try:
                # try to load fixture and if loaded remove it from the array
                load_fixture(fl)
                print("LOADED: {}".format(fl))
                fixture_locations.remove(fl)
            except IntegrityError as e:
                errors.append(str(e))

        # if import did not occur this iteration raise exception due to
        # missing foreign key reference
        length_after = len(fixture_locations)
        if length_before == length_after:
            raise IntegrityError(' '.join(errors))
Gelding answered 16/11, 2017 at 19:29 Comment(0)
Y
0

This works well for me; it finds all files located in fixtures directories within the the src directory:

python manage.py loaddata \
    $(ls -1 src/**/fixtures/* | tr '\n' '\0' | xargs -0 -n 1 basename | tr '\n' ' ')
Yahiya answered 25/1, 2019 at 5:51 Comment(0)
H
0
python manage.py loaddata ./*/fixtures/*.json

This command will look for the folder fixture in all the directory and then it will pick up all the files with json extension and will install the fixtures.

This way you won't have to have just one folder for fixtures instead you can have fixtures on app level and in multiple apps.

It will work with the ideal folder structure like this -

app_name_1
├──fixtures
├────json_file_1.json
├────json_file_2.json
app_name_2
├──fixtures
├────json_file_3.json
Hanford answered 26/1, 2022 at 6:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.