我用manage.py dumpdata
备份了DB,现在我有一个文件想和manage.py loaddata
一起使用,但我希望在加载数据之前对数据执行一些自定义逻辑。这是因为我正在将数据迁移到不同的结构。如何将数据放入python对象中,以便执行自定义逻辑?
以下代码提供了从fixture文件加载数据的两种方法:
- 使用Python的原生JSON模块。这样做的好处是,如果您的模型发生了更改,您可以加载数据,将其操作为所需的形式并保存
- 使用Django
deserializer
。这样做的好处是,它可以为您创建模型实例,但如果您正在迁移代码,而模型实例代码不再存在,这可能是一个问题
""" Refer to help variable below
"""
import json
from pathlib import Path
from django.core import serializers
from django.core.management.base import BaseCommand
class Command(BaseCommand):
help = "Customized load data for DB migration"
def iter_json(self, file):
""" Iterates dumpdata dson file and yields a model name / field dict pairs.
e.g.
model = 'common.sitesettings'
fields = {'name': 'ACME Products', 'timezone': 'Africa/Johannesburg'}
"""
with open(file, "r") as f:
data = json.loads(f.read())
for obj in data:
yield obj['model'], obj['fields']
def iter_data(self, file):
""" Iterates dumpdata dson file and yields model instances.
The downside to this approach is that one requires the code for the models,
which is not neccessarily the case when migrating data/
e.g.
model_instance = <SiteSettings: ACNE Products ()>
"""
data = self.parse_json(file)
with open(file, "r") as f:
data_str = f.read()
for item in serializers.deserialize("json", data_str):
# item.save() would save it (unconfirmed)
model_instance = item.object
yield model_instance
def add_arguments(self, parser):
parser.add_argument(
'file',
type=str,
help='Location of the manage.py dumpdata backup file',
)
def handle(self, **options):
file = options['file']
if not Path(file).is_file():
print(f"File '${file}' does not exist. EXIT.")
return
print(f"START - Customised loaddata")
for model, fields in self.iter_json(file):
print(model, fields)
for instance in self.iter_data(file):
print(instance)
print(f"COMPLETE.")