Django
마이그레이션
수색…
매개 변수
django-admin 명령 | 세부 |
---|---|
makemigrations <my_app> | my_app 대한 마이그레이션 생성 |
makemigrations | 모든 앱에 대해 이전 생성 |
makemigrations --merge | 모든 앱의 마이그레이션 충돌 해결 |
makemigrations --merge <my_app> | my_app 마이그레이션 충돌 해결 |
makemigrations --name <migration_name> <my_app> | 에 대한 마이그레이션 생성 my_app 이름으로 migration_name |
migrate <my_app> | 데이터베이스에 my_app 보류중인 마이그레이션 적용 |
migrate | 데이터베이스에 대기중인 모든 마이그레이션 적용 |
migrate <my_app> <migration_name> | migration_name 적용 또는 적용 취소 |
migrate <my_app> zero | my_app 에서 모든 이전 적용 취소 |
sqlmigrate <my_app> <migration_name> | 명명 된 이전을 위해 SQL을 인쇄합니다. |
showmigrations | 모든 앱에 대한 모든 이전을 표시합니다. |
showmigrations <my_app> | my_app 모든 이전을 표시합니다. |
마이그레이션 작업
Django는 마이그레이션을 사용하여 모델에 대한 변경 사항을 데이터베이스에 전파합니다. 대부분의 시간에 장고가 생성 할 수 있습니다.
마이그레이션을 만들려면 다음을 실행하십시오.
$ django-admin makemigrations <app_name>
그러면 app_name
의 migration
하위 모듈에 마이그레이션 파일이 만들어집니다. 첫 번째 마이그레이션은 0001_initial.py
, 다른 하나는 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]
는 이주가 데이터베이스로 전파되었음을의 L합니다. -
[ ]
는 이주가 사용자 데이터베이스로 전파되지 않았 음을 의미합니다.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
수동 마이그레이션
때때로 장고에 의해 생성 된 마이그레이션만으로는 충분하지 않습니다. 특히 데이터 이전 을 원할 때 그렇습니다.
예를 들어, 당신은 그런 모델을 가지고 있습니다 :
class Article(models.Model):
title = models.CharField(max_length=70)
이 모델에는 이미 기존 데이터가 있으며 이제 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
라고 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>
마이그레이션 충돌 해결
소개
때때로 마이그레이션이 충돌하여 마이그레이션을 성공적으로 수행하지 못하게합니다. 이것은 많은 scenerio에서 발생할 수 있지만 팀과 함께 하나의 앱을 개발할 때 정기적으로 발생할 수 있습니다.
일반적인 마이그레이션 충돌은 소스 제어를 사용하는 동안 발생합니다. 특히 지점 별 기능 사용 방법이 사용되는 경우 특히 그렇습니다. 이 시나리오에서는 name
과 address
속성을 가진 Reporter
라는 모델을 사용할 것입니다.
이 시점에서 두 명의 개발자가 기능을 개발할 예정이므로 Reporter
모델의 초기 사본을 얻게됩니다. 개발자 A는 추가 age
파일 결과 0002_reporter_age.py
파일을. 개발자 B는 추가 bank_account
에서 resulsts 필드 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에 대해 새 필드를 추가하고 null로 표시해야합니다 (링크하는 모델도 포함됨).
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
작업 하나를 추가하려고합니다. 이 경우 다음과 같이 보일 수 있습니다.
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
, 실제로 모든 작업을 완료 할 수 있으며 모든 것에 대해 새로운 artist_link
필드를 사용합니다. 또는 약간의 정리 작업을 수행하려는 경우 두 개의 마이그레이션을 추가로 작성하려고합니다.
첫 번째 이전을 위해 원래 필드 인 artist
를 삭제해야합니다. 두 번째로 이전하려면 새 필드 artist_link
이름을 artist
변경하십시오.
이것은 장고가 작업을 적절하게 인식 할 수 있도록 여러 단계로 이루어집니다.