我有一个包含3个模型的应用程序,它们以父子方式相互引用:
class A(Model):
# ...
class B(Model):
a = ForeignKey(A)
# ...
class C(Model):
b = ForeignKey(B)
# ...
在我的生产数据库中,我有数百个A类对象,其下面有数千个子对象。我现在想要仅为(特定)少数对象创建一个夹具。如果我运行此命令,我的输出将变得巨大:
python manage.py dumpdata ca_myapp -o /tmp/my_app_dump.json
但是,当我使用此命令限制输出时:
python manage.py dumpdata ca_myapp.A -o /tmp/myapp_dump.json --pks pk1, pk2, pk3
然后只反序列化A对象,而不是它们的子代。如何轻松地创建包含少数对象及其子项的fixture文件?
答案 0 :(得分:1)
来自Django documentation regarding dumpdata
django-admin dumpdata [app_label[.ModelName] [app_label[.ModelName]...]]
所以在你的情况下
python manage.py dumpdata ca_myapp.A ca_myapp.B ca_myapp.C
其他方式是使用exclude
--exclude EXCLUDE,-e EXCLUDE防止转储特定的应用程序或模型(以app_label.ModelName的形式指定)。如果 如果指定了型号名称,则输出将仅限于该型号, 而不是整个应用程序。您还可以混合应用程序名称 和型号名称。
如果要排除多个应用程序,请传递--exclude以上 一旦
如果我没有正确理解问题,并且您在询问是否可以选择几个pks并遵循他们之间目前无法使用dumpdata的关系, 但是你可以轻松准备你的数据库来保存必要的数据。
答案 1 :(得分:0)
我现在写了一个Django命令,首先检查我想要获取哪些pks,以及他们拥有哪些子代,以获取所有相关对象。
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))