2017-11-14 13 views
1

documentationと同様にSO questiondjango-seed packageを見てきましたが、これらのどれも私がしようとしているものに合っていないようです。Django 1.10シードデータベース

基本的に、私はGamesモデルを外部APIからプログラムでシードしたいと思いますが、私が見つけることができるすべての情報は、最初にフィクスチャーを生成することに依存しているようです。

たとえば、Ruby/Railsでは、seed.rbに直接書き込んで、必要に応じてデータベースをシードできます。

Djangoでも同様の機能を利用できますか?または、まずAPIからフィクスチャを生成してインポートする必要がありますか?

+2

Djangoの 'manage.py loaddata'はテキストファイルを解析してデータベースに挿入します。最初の移行では、[リンクされたドキュメント](https://docs.djangoproject.com/en/1.11/howto/initial-data/#providing-initial-data-html)の下部にあるように、プログラムで行うことができます移行あり)。 – Blender

+0

はい、テキストファイルを作成しないようにしています。不要です。 – Darkstarone

+2

移行には、ハードコードされた初期データが含まれている必要はありません。Pythonスクリプトです。 'RunPython'のマイグレーションを使用して、APIからデータをストリーミングしてデータベースに挿入する関数を作成するだけです。最初の移行が実行されると自動的に実行され、移行ではトランザクションが自動的に利用されるため、データベースの状態が破壊されることはありません。 – Blender

答えて

3

このためにデータ移行を使用できます。あなたの空の移行で

$ python manage.py makemigrations yourappname --empty 

、あなたのデータをロードし、migrations.RunPython操作を追加するための関数を作成:まず、アプリの空の移行を作成します。ここDjango documentation on migrationsから1の修正版です:

from __future__ import unicode_literals 
from django.db import migrations 

def stream_from_api(): 
    ... 

def load_data(apps, schema_editor): 
    # We can't import the Person model directly as it may be a newer 
    # version than this migration expects. We use the historical version. 
    Person = apps.get_model('yourappname', 'Person') 

    for item in stream_from_api(): 
     person = Person(first=item['first'], last=item['last'], age=item['age']) 
     person.save() 

class Migration(migrations.Migration): 
    dependencies = [('yourappname', '0009_something')] 
    operations = [migrations.RunPython(load_data)] 

あなたは、単純なデータの多くを持っている場合、あなたはバルクの作成方法から利益を得るかもしれません:

from __future__ import unicode_literals 
from django.db import migrations 

def stream_from_api(): 
    ... 

def load_data(apps, schema_editor): 
    # We can't import the Person model directly as it may be a newer 
    # version than this migration expects. We use the historical version. 
    Person = apps.get_model('yourappname', 'Person') 

    def stream_people(): 
     for item in stream_from_api(): 
      yield Person(first=item['first'], last=item['last'], age=item['age']) 

    # Adjust (or remove) the batch size depending on your needs. 
    # You won't be able to use this method if your objects depend on one-another 
    Person.objects.bulk_create(stream_people(), batch_size=10000) 

class Migration(migrations.Migration): 
    dependencies = [('yourappname', '0009_something')] 
    operations = [migrations.RunPython(load_data)] 

移行ができるという利点を持っています自動的にトランザクションに格納されるので、いつでも移行を停止することができ、データベースが不整合な状態になることはありません。

+0

あなたの 'load_data'関数では、とにかく' apps.get_model() 'を使って基本Userモデルをロードしますか?私はそこにあることを知っている、それを行う方法がわからない。 – Tunn

+1

@Tunn: 'apps.get_model( 'auth'、 'User')'は動作するはずです。 – Blender

1

データを作成するモデルのGamesにいくつかのクラスメソッドを書き込むことができますか?おそらくこのメソッドは外部APIを照会し、オブジェクトをgamesというリストとしてパッケージ化し、Games.objects.bulk_create(games)を使用してデータベースに挿入します。

+0

これはかなり理想的ですね。ありがとう。 – Darkstarone

関連する問題