サーチ…


パラメーター

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つのアプリを開発するときに定期的に発生する可能性があります。

ソース制御を使用している間、一般的な移行の競合が発生します。特に、ブランチフィーチャごとの方法が使用されている場合に発生します。このシナリオでは、 nameaddress属性を持つReporterというモデルを使用しaddress

この時点で2人の開発者がフィーチャーを開発しているので、両方ともReporterモデルの最初のコピーを取得します。開発者Aはファイル0002_reporter_age.pyファイルの結果となるageを追加します。開発者Bは、 bank_accountするbank_accountフィールドを追加し0002_reporter_bank_account 。これらの開発者がコードを結合して移行を移行しようとすると、移行の競合が発生しました。

この競合は、これらの移行が同じモデルReporter変更するために発生します。さらに、新しいファイルは両方とも0002で始まります。

移行のマージ

それを行うにはいくつかの方法があります。以下は推奨される順序です:

  1. 最も単純な修正は、makemigrationsコマンドを--mergeフラグで実行することです。

    python manage.py makemigrations --merge <my_app>
    

    これにより、以前の紛争を解決する新しい移行が作成されます。

  2. この特別なファイルが開発環境で個人的な理由で歓迎されない場合、競合する移行を削除することもできます。その後、通常の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が正しく操作を認識できるように、複数のステップで実行されます。



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow