我能否在Django中仅对单个模型执行dumpdata
,而不是整个应用程序?如果可以,如何操作?
对于一个应用程序,操作方式如下:
python manage.py dumpdata myapp
然而,我想要一些特定的模型被转储,例如"myapp.mymodel"。原因是,我在同一个应用程序中有一些巨大的数据集(超过300万条记录),我不想进行转储。
我能否在Django中仅对单个模型执行dumpdata
,而不是整个应用程序?如果可以,如何操作?
对于一个应用程序,操作方式如下:
python manage.py dumpdata myapp
然而,我想要一些特定的模型被转储,例如"myapp.mymodel"。原因是,我在同一个应用程序中有一些巨大的数据集(超过300万条记录),我不想进行转储。
从1.1版本开始,Django dumpdata
管理命令允许你从单个表中导出数据:
./manage.py dumpdata myapp1 myapp2.my_model
你也可以在命令行上分开多个应用程序和模型。以下是规范定义:
django-admin dumpdata [app_label[.ModelName] [app_label[.ModelName] ...]]
dumpdata
命令后加上标志--indent 4
可以生成易读的JSON格式。 - Valery Ramusik正如所指出的,你不能通过 Django 1.0 中的 manage.py 命令来完成此操作。但你可以使用脚本导出 JSON 文件,并使用 loaddata
加载它:
from django.core import serializers
from myproject.myapp import models
data = serializers.serialize("json", models.MyModel.objects.all())
out = open("mymodel.json", "w")
out.write(data)
out.close()
针对特定文件的特定模型:
python manage.py dumpdata app_label.ModelName > specific_file.json
并将其加载到另一个应用程序中:首先将文件移动或复制到您想要处理它的应用程序中,然后:
python manage.py loaddata specific_file.json
从Django模型中以JSON格式获取所有数据。
语法:
python manage.py dumpdata app_name.model_name
比如说,在 Django 中从默认的认证应用程序中的 group_permission 模型中转储数据。
python manage.py dumpdata auth.group_permission
请查看控制台以获取输出。
我认为你在问题中已经提供了解决方案。你可以按照以下方式转储单个模型:
./manage.py dumpdata myapp.my_model
为了成功,我必须重复说两遍,并且两次指定模型,例如:
./manage.py dumpdata myapp2.my_model myapp2.my_model
./manage.py dumpdata myapp2 myapp2.my_model
尽管我已经指定了my_model,但是所有的模型都淹没在了我的app2中。
对于像我这样的Django和Python新手,这可能会很有用:
如果你只想转储单个行(显然是单个表的),例如你的应用程序名为"merchant",模型也被命名为“Merchant”,通常使用全限定名称导入它就像这样: merchant.models.Merchant
; 不要试图使用这个名称。语法如下:
# only dumps the merchant with id = 123, pretty printed
python manage.py dumpdata merchant.Merchant --pks 123 --indent 2
--pks PRIMARY_KEYS 仅输出由逗号分隔的主键列表指定的对象。仅在转储一个模型时可用。默认情况下,输出模型的所有记录。
将其写入特定文件:
python manage.py dumpdata app_label.ModelName app_label.ModelName2 > fixtures/specic.json
我认为接受的答案已经过时了,需要在2023年进行详细的更新。
我曾经遇到过类似的问题,需要为来自不同应用程序的特定模型创建固定装置,并具有特定的ID。此外,我只需要为所有模型创建一个装置,这样我们就不必加载单独的装置,而是只需加载一个装置即可。
我通过创建自定义命令来完成所有这些操作,该命令在内部调用dumpdata
以获取每个特定模型的特定ID,如下所示:
products/models.py
class Product(models.Model):
name = models.CharField(max_length=200)
price = models.DecimalField(max_digits = 5, decimal_places = 2)
reviews/models.py
class Review(models.Model):
title = models.CharField(max_length=200)
text = models.TextField()
timestamp = models.DateTimeField(auto_now_add=True)
rating = models.PositiveIntegerField(default=0)
product = models.ForeignKey(Product, on_delete=models.CASCADE)
def natural_key(self):
return self.title, self.timestamp
class Response(models.Model):
text = models.TextField()
timestamp = models.DateTimeField(auto_now_add=True)
generate_fixture.py
from django.core.management import BaseCommand, call_command
from io import StringIO
import json
class Command(BaseCommand):
def add_arguments(self, parser):
parser.add_argument('id', type=int, help='Primary Key Of Product')
def handle(self, *args, **options):
id = options.get('id')
if product := Product.objects.filter(id=id).first():
product_fixture = self.get_fixture('products.Product', str(id))
review_ids = list(
Review.objects.filter(product__id=id).values_list('id',flat=True)
)
review_ids = ','.join([str(review_id) for review_id in review_ids])
review_fixture = self.get_fixture('reviews.Review', review_ids)
output = [json.loads(product_fixture)]
output.extend(json.loads(review_fixture))
with open('model_fixtures.json', "w") as file:
json.dump(output, file)
else:
print(f"Product with id {id} does not exists!")
def get_fixture(self, label, pks):
args = ['dumpdata', '--natural-foreign', '--natural-primary', label]
with StringIO() as buffer:
call_command(*args, pks=pks, stdout=buffer)
data = buffer.getvalue()
return data
现在你可以像这样使用id运行命令:
python manage.py generate_fixture 50
模型的fixture将会生成一个fixture文件,可以通过以下方式加载:
python manage.py loaddata model_fixtures.json
注意:代码未经过测试。
get_fixture
的第一个参数需要是“self”,我们还需要注意输出的格式,以便它能够与loaddata命令一起使用。https://dev59.com/HrHma4cB1Zd3GeqPQL-r#54617472 - Mike S