使用Django 1.7和数据迁移加载初始数据 [英] Loading initial data with Django 1.7 and data migrations
问题描述
在1.7之前,我曾经加载初始数据 fixture / initial_data.json
文件,它加载了 python manage.py syncdb
命令(创建数据库时) 。
现在,我开始使用迁移,这种行为已被弃用:
如果应用程序使用迁移,则不会自动加载固定装置。
由于Django 2.0中的应用程序需要迁移,所以这种行为被认为是不推荐的。如果要加载应用程序的初始数据,请考虑在数据迁移中进行。
( https: //docs.djangoproject.com/en/1.7/howto/initial-data/#automatically-loading-initial-data-fixtures )
官方文档不有一个明确的例子,如何做,所以我的问题是:
使用数据迁移导入这些初始数据的最好方式是什么?
- 将多个调用的Python代码写入
mymodel.create(...)
, - 使用或编写Django功能(喜欢调用
loaddata
)从JSON夹具文件加载数据。
我更喜欢第二个选项。 p>
我不知道t使用南方,因为Django似乎现在可以自己做。
假设你有一个夹具文件在< yourapp> /fixtures/initial_data.json
-
创建您的空迁移:
在Django 1.7中:
python manage.py makemigrations - 空< yourapp>
在Django 1.8+中,您可以提供一个名称:
python manage.py makemigrations --empty< yourapp> --name load_intial_data
-
编辑您的迁移文件
< yourapp> /migrations/0002_auto_xxx.py
2.1。自定义实现,灵感来自Django'
loaddata
(初始答案):从sys import path导入os
from django.core import serializers
fixture_dir = os.path.abspath(os.path.join(os.path.dirname(__ file__) ,'../fixtures'))
fixture_filename ='initial_data.json'
def load_fixture(apps,schema_editor):
fixture_file = os.path.join(fixture_dir,
fixture = open(fixture_file,'rb')
objects = serializers.deserialize('json',fixture,ignorenonexistent = True)
对象中的obj:
obj.save()
fixture.close()
def unload_fixture(apps,schema_editor):
严格删除此模型的所有条目...
MyModel = apps.get_model(yourapp,ModelName)
MyModel.objects.all()。delete()
class Migration(migrations.Migration ):
依赖关系= [
('yourapp ,'0001_initial'),
]
operations = [
migrations.RunPython(load_fixture,reverse_code = unload_fixture),
]
2.2。
load_fixture
(per @ juliocesar的建议)的一个更简单的解决方案:from django.core.management import call_command
fixture_dir = os.path.abspath(os.path.join(os.path.dirname(__ file__),'../fixtures'))
fixture_filename ='initial_data.json'
def load_fixture(apps,schema_editor):
fixture_file = os.path.join(fixture_dir,fixture_filename)
call_command('loaddata',fixture_file )
如果要使用自定义目录,则很有用
2.3。调用
loaddata
与app_label
将从中加载灯具 < yourapp>
的fixtures
dir automatically:from django.core.management import call_command
fixture ='initial_data'
def load_fixture(apps,schema_editor):
call_command('loaddata' ,夹具,app_label ='yourapp')
如果不指定
app_label
,loaddata将尝试从所有应用程序夹具目录中加载fixture
filename(你可能不会 -
运行
python manage.py migrate< yourapp>
I recently switched from Django 1.6 to 1.7, and I began using migrations (I never used South).
Before 1.7, I used to load initial data with a fixture/initial_data.json
file, which was loaded with the python manage.py syncdb
command (when creating the database).
Now, I started using migrations, and this behavior is deprecated :
If an application uses migrations, there is no automatic loading of fixtures. Since migrations will be required for applications in Django 2.0, this behavior is considered deprecated. If you want to load initial data for an app, consider doing it in a data migration. (https://docs.djangoproject.com/en/1.7/howto/initial-data/#automatically-loading-initial-data-fixtures)
The official documentation does not have a clear example on how to do it, so my question is :
What is the best way to import such initial data using data migrations :
- Write Python code with multiple calls to
mymodel.create(...)
, - Use or write a Django function (like calling
loaddata
) to load data from a JSON fixture file.
I prefer the second option.
I don't want to use South, as Django seems to be able to do it natively now.
Assuming you have a fixture file in <yourapp>/fixtures/initial_data.json
Create your empty migration:
In Django 1.7:
python manage.py makemigrations --empty <yourapp>
In Django 1.8+, you can provide a name:
python manage.py makemigrations --empty <yourapp> --name load_intial_data
Edit your migration file
<yourapp>/migrations/0002_auto_xxx.py
2.1. Custom implementation, inspired by Django'
loaddata
(initial answer):import os from sys import path from django.core import serializers fixture_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '../fixtures')) fixture_filename = 'initial_data.json' def load_fixture(apps, schema_editor): fixture_file = os.path.join(fixture_dir, fixture_filename) fixture = open(fixture_file, 'rb') objects = serializers.deserialize('json', fixture, ignorenonexistent=True) for obj in objects: obj.save() fixture.close() def unload_fixture(apps, schema_editor): "Brutally deleting all entries for this model..." MyModel = apps.get_model("yourapp", "ModelName") MyModel.objects.all().delete() class Migration(migrations.Migration): dependencies = [ ('yourapp', '0001_initial'), ] operations = [ migrations.RunPython(load_fixture, reverse_code=unload_fixture), ]
2.2. A simpler solution for
load_fixture
(per @juliocesar's suggestion):from django.core.management import call_command fixture_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '../fixtures')) fixture_filename = 'initial_data.json' def load_fixture(apps, schema_editor): fixture_file = os.path.join(fixture_dir, fixture_filename) call_command('loaddata', fixture_file)
Useful if you want to use a custom directory.
2.3. Simplest: calling
loaddata
withapp_label
will load fixtures from the<yourapp>
'sfixtures
dir automatically :from django.core.management import call_command fixture = 'initial_data' def load_fixture(apps, schema_editor): call_command('loaddata', fixture, app_label='yourapp')
If you don't specify
app_label
, loaddata will try to loadfixture
filename from all apps fixtures directories (which you probably don't want).Run it
python manage.py migrate <yourapp>
这篇关于使用Django 1.7和数据迁移加载初始数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!