Django
移行
サーチ…
パラメーター
django-admin コマンド | 詳細 |
---|---|
makemigrations <my_app> | my_app マイグレーションを生成する |
makemigrations | すべてのアプリケーションの移行を生成する |
makemigrations --merge | すべてのアプリケーションの移行の競合を解決する |
makemigrations --merge <my_app> | my_app 移行の競合を解決する |
makemigrations --name <migration_name> <my_app> | migration_nameという名前のmy_app 移行を生成しmigration_name |
migrate <my_app> | my_app 保留中の移行をデータベースに適用する |
migrate | すべての保留中の移行をデータベースに適用する |
migrate <my_app> <migration_name> | migration_name 適用または適用解除する |
migrate <my_app> zero | my_appですべての移行をmy_app |
sqlmigrate <my_app> <migration_name> | 名前付き移行のSQLを出力します。 |
showmigrations | すべてのアプリケーションのすべての移行を表示します |
showmigrations <my_app> | my_app 内のすべての移行を表示しmy_app |
移行の作業
Djangoはマイグレーションを使用して、モデルに加えた変更をデータベースに伝播します。ほとんどの場合、djangoはそれらを生成することができます。
移行を作成するには、以下を実行します。
$ django-admin makemigrations <app_name>
これにより、 app_name
migration
サブモジュールにマイグレーション・ファイルが作成されます。最初の移行は0001_initial.py
と呼ばれ、もう1つは0002_
、 0003
、次に開始されます。
<app_name>
を省略すると、すべてのINSTALLED_APPS
移行が作成されます。
移行をデータベースに伝播するには、次のコマンドを実行します。
$ django-admin migrate <app_name>
すべての移行を表示するには、次のコマンドを実行します。
$ django-admin showmigrations app_name
app_name
[X] 0001_initial
[X] 0002_auto_20160115_1027
[X] 0003_somemodel
[ ] 0004_auto_20160323_1826
-
[X]
は、移行がデータベースに伝播されたことを意味します -
[ ]
は、マイグレーションがデータベースに伝播されなかったことを意味します。django-admin migrate
を使用してそれを伝播する
移行を元に戻すこともできます。これは、移行名をmigrate command
渡すことで実行できます。上記の移行のリスト( django-admin showmigrations
示されている)を見ると、
$ django-admin migrate app_name 0002 # Roll back to migration 0002
$ django-admin showmigrations app_name
app_name
[X] 0001_initial
[X] 0002_auto_20160115_1027
[ ] 0003_somemodel
[ ] 0004_auto_20160323_1826
手動移行
時々、Djangoによって生成された移行は十分ではありません。これは、 データ移行を行う場合に特に当てはまります。
たとえば、あなたはそのようなモデルを持っています:
class Article(models.Model):
title = models.CharField(max_length=70)
このモデルにはすでに既存のデータがあり、今ではSlugField
を追加しSlugField
:
class Article(models.Model):
title = models.CharField(max_length=70)
slug = models.SlugField(max_length=70)
フィールドを追加するために移行を作成しましたが、 title
に応じて既存のすべての記事のスラッグを設定します。
もちろん、あなたは端末の中で次のようなことをすることができます:
$ django-admin shell
>>> from my_app.models import Article
>>> from django.utils.text import slugify
>>> for article in Article.objects.all():
... article.slug = slugify(article.title)
... article.save()
...
>>>
しかし、あなたはあなたのすべての環境(つまり、あなたのオフィスのデスクトップ、ラップトップ、など)でこれを行う必要があります。あなたの同僚は同様にそうしなければなりません。あなたはステージング時にそれについて考える必要があります。ライブ。
これを一度に行うために、私たちは移行でそれを行います。最初に空の移行を作成します。
$ django-admin makemigrations --empty app_name
これにより、空の移行ファイルが作成されます。それを開くと、基本骨格が含まれています。以前の移行で0023_article_slug
という名前が付けられ、この名前の名前が0024_auto_20160719_1734
ます。移行ファイルには次のように記述します。
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-07-19 15:34
from __future__ import unicode_literals
from django.db import migrations
from django.utils.text import slugify
def gen_slug(apps, schema_editor):
# We can't import the Article model directly as it may be a newer
# version than this migration expects. We use the historical version.
Article = apps.get_model('app_name', 'Article')
for row in Article.objects.all():
row.slug = slugify(row.name)
row.save()
class Migration(migrations.Migration):
dependencies = [
('hosting', '0023_article_slug'),
]
operations = [
migrations.RunPython(gen_slug, reverse_code=migrations.RunPython.noop),
# We set `reverse_code` to `noop` because we cannot revert the migration
# to get it back in the previous state.
# If `reverse_code` is not given, the migration will not be reversible,
# which is not the behaviour we expect here.
]
偽の移行
移行が実行されると、Djangoは移行の名前をdjango_migrationsテーブルに保存します。
既存のスキーマの初期移行の作成と偽装
あなたのアプリに既にモデルとデータベーステーブルがあり、移行がない場合。まず、アプリの初期移行を作成します。
python manage.py makemigrations your_app_label
適用された初期移行を偽装する
python manage.py migrate --fake-initial
すべてのアプリケーションですべての移行を偽装する
python manage.py migrate --fake
偽の単一アプリの移行
python manage.py migrate --fake core
偽の単一移行ファイル
python manage.py migrate myapp migration_name
移行ファイルのカスタム名
makemigrations --name <your_migration_name>
オプションを使用すると、生成された名前を使用する代わりにマイグレーションの名前を付けることができます。
python manage.py makemigrations --name <your_migration_name> <app_name>
移行の競合の解決
前書き
時には移行が競合し、移行が不成功に終わってしまうことがあります。これは多くのシーンで発生する可能性がありますが、チームで1つのアプリを開発するときに定期的に発生する可能性があります。
ソース制御を使用している間、一般的な移行の競合が発生します。特に、ブランチフィーチャごとの方法が使用されている場合に発生します。このシナリオでは、 name
とaddress
属性を持つReporter
というモデルを使用しaddress
。
この時点で2人の開発者がフィーチャーを開発しているので、両方ともReporter
モデルの最初のコピーを取得します。開発者Aはファイル0002_reporter_age.py
ファイルの結果となるage
を追加します。開発者Bは、 bank_account
するbank_account
フィールドを追加し0002_reporter_bank_account
。これらの開発者がコードを結合して移行を移行しようとすると、移行の競合が発生しました。
この競合は、これらの移行が同じモデルReporter
変更するために発生します。さらに、新しいファイルは両方とも0002で始まります。
移行のマージ
それを行うにはいくつかの方法があります。以下は推奨される順序です:
最も単純な修正は、makemigrationsコマンドを--mergeフラグで実行することです。
python manage.py makemigrations --merge <my_app>
これにより、以前の紛争を解決する新しい移行が作成されます。
この特別なファイルが開発環境で個人的な理由で歓迎されない場合、競合する移行を削除することもできます。その後、通常の
makemigrations
コマンドを使用して新しい移行を行うことができます。カスタム移行が書かれている場合は、のようなmigrations.RunPython
、この方法を用いて会計処理する必要があります。
CharFieldを外部キーに変更する
最初に、 discography
と呼ばれるアプリケーションの中で、これがあなたの初期モデルであると仮定しましょう。
from django.db import models
class Album(models.Model):
name = models.CharField(max_length=255)
artist = models.CharField(max_length=255)
さて、アーティストの代わりにForeignKeyを使いたいと思っています。これはやや複雑なプロセスで、いくつかのステップで実行する必要があります。
ステップ1、ForeignKeyに新しいフィールドを追加し、それをヌルとしてマークします(リンク先のモデルも含まれています)。
from django.db import models
class Album(models.Model):
name = models.CharField(max_length=255)
artist = models.CharField(max_length=255)
artist_link = models.ForeignKey('Artist', null=True)
class Artist(models.Model):
name = models.CharField(max_length=255)
...この変更のための移行を作成します。
./manage.py makemigrations discography
ステップ2、新しいフィールドに値を入力します。これを行うには、空の移行を作成する必要があります。
./manage.py makemigrations --empty --name transfer_artists discography
この空の移行が完了したら、レコードをリンクするためにRunPython
操作を1つ追加する必要があります。この場合、次のようになります。
def link_artists(apps, schema_editor):
Album = apps.get_model('discography', 'Album')
Artist = apps.get_model('discography', 'Artist')
for album in Album.objects.all():
artist, created = Artist.objects.get_or_create(name=album.artist)
album.artist_link = artist
album.save()
データが新しいフィールドに転送されたので、新しいartist_link
フィールドを使用して、実際にすべてをそのまま残すことができます。または、少しクリーンアップを行いたい場合は、2つ以上のマイグレーションを作成する必要があります。
あなたの最初の移行のために、元のフィールドartist
を削除したいでしょう。 2回目の移行では、新しいフィールドartist_link
名前をartist
変更します。
これは、Djangoが正しく操作を認識できるように、複数のステップで実行されます。