Reputation: 6858
I have an app with 3 models that refer to each other in a parent-child way:
class A(Model):
# ...
class B(Model):
a = ForeignKey(A)
# ...
class C(Model):
b = ForeignKey(B)
# ...
In my production database, I have hundreds objects of type A, with thousands of child objects below it. I now want to create a fixture for only a (specific) handful objects. If I run this command, my output will become huge:
python manage.py dumpdata ca_myapp -o /tmp/my_app_dump.json
However, when I restrict the output using this command:
python manage.py dumpdata ca_myapp.A -o /tmp/myapp_dump.json --pks pk1, pk2, pk3
Then only the A objects are deserialized, but not their children. How can I easily create a fixture file with a handful of objects and their children?
Upvotes: 5
Views: 6140
Reputation: 6858
I have written now a Django command that first checks which pks I want to fetch, and which children they have, to fetch all related objects.
import logging
import os
from django.core.management import BaseCommand, call_command
logger = logging.getLogger(__name__)
A = {'pk1', 'pk2', 'pk3'}
class Command(BaseCommand):
def __init__(self, stdout=None, stderr=None, no_color=False):
super().__init__(stdout, stderr, no_color)
self.settings = None
self.a = set()
@property
def tmp_dir(self):
return '/tmp'
def handle(self, *args, **options):
self.settings = options.get('settings')
# TODO: Make list of A an optional argument
a_pks = A
self.dump_objects('ca_myapp.A', pks=a_pks)
b_pks = B.objects.filter(a_id__in=a_pks).values_list('pk', flat=True)
self.dump_objects('ca_myapp.B', pks=b_pks)
c_pks = C.objects.filter(b_id__in=b_pks).values_list('pk', flat=True)
self.dump_objects('ca_myapp.C', pks=c_pks)
def dump_objects(self, model_name: str, pks: set):
if pks:
call_command('dumpdata', model_name,
'--pks', ','.join(pks),
'--indent', '2',
'-o', os.path.join(self.tmp_dir, '{}.json'.format(model_name)),
'--settings', self.settings)
else:
logger.warning('No objects for model {} found'.format(model_name))
Upvotes: 4
Reputation: 15758
From Django documentation regarding dumpdata
django-admin dumpdata [app_label[.ModelName] [app_label[.ModelName]...]]
So in your case
python manage.py dumpdata ca_myapp.A ca_myapp.B ca_myapp.C
Other way around would be to use exclude
--exclude EXCLUDE, -e EXCLUDEPrevents specific applications or models (specified in the form of app_label.ModelName) from being dumped. If you specify a model name, the output will be restricted to that model, rather than the entire application. You can also mix application names and model names.
If you want to exclude multiple applications, pass --exclude more than once
If I haven't properly understood question and you are asking if it is possible to select just few of pks and follow their relationship that is currently not possible with dumpdata, but you can easily prepare your db to hold just data that is necessary .
Upvotes: 1