使用Django 1.7和数据迁移加载初始数据 [英] Loading initial data with Django 1.7 and data migrations

查看:530
本文介绍了使用Django 1.7和数据迁移加载初始数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近从Django 1.6切换到1.7,我开始使用迁移(我从未使用过South)。



在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


官方文档不有一个明确的例子,如何做,所以我的问题是:



使用数据迁移导入这些初始数据的最好方式是什么?


  1. 将多个调用的Python代码写入 mymodel.create(...)

  2. 使用或编写Django功能(喜欢调用 loaddata )从JSON夹具文件加载数据。

我更喜欢第二个选项。 p>

我不知道t使用南方,因为Django似乎现在可以自己做。

解决方案

假设你有一个夹具文件在< yourapp> /fixtures/initial_data.json


  1. 创建您的空迁移:



    在Django 1.7中:

      python manage.py makemigrations - 空< yourapp> 

    在Django 1.8+中,您可以提供一个名称:

      python manage.py makemigrations --empty< yourapp> --name load_intial_data 


  2. 编辑您的迁移文件< 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(你可能不会


  3. 运行

      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 :

  1. Write Python code with multiple calls to mymodel.create(...),
  2. 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

  1. 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
    

  2. 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 with app_label will load fixtures from the <yourapp>'s fixtures 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 load fixture filename from all apps fixtures directories (which you probably don't want).

  3. Run it

    python manage.py migrate <yourapp>
    

这篇关于使用Django 1.7和数据迁移加载初始数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆