2013-04-25 1 views
4

을 만들어이 모델장고 남쪽 - NOT NULL 외래 키

class Mystery(models.Model): 
    first = models.CharField(max_length=256) 
    second = models.CharField(max_length=256) 
    third = models.CharField(max_length=256) 
    player = models.ForeignKey(Player) 

내가 플레이어 외래 키를 추가해야하지만 사용하여 마이그레이션 할 때 한국은 내가 거짓 = 널 아 파크이를 만들 수 없습니다 것 같다. 아직 NULL NOT 입니다

필드 'Mystery.player'지정된 기본이없는 :이 메시지가 있습니다. 이 필드를 추가하기 때문에 기존 행에 사용할 기본값 인 을 지정해야합니다. 당신이 하시겠습니까 :
1. 지금 종료 한 models.py의 필드에 기본을 추가
2. 지금

내가이 명령을 사용하는 기존의 컬럼에 사용하는 일회성 값을 지정합니다 :

manage.py의 schemamigration의 myapp와

덕분에 많은 --auto!

+2

는 다음 남쪽으로 알고 있어야 7. 실행이 비어있을 수 없기 때문에, player' 필드'에 무엇을 넣어 값. 한 가지 가능한 해결책은 다음과 같습니다. 2. 일회용을 지정하고 1을 입력하십시오. 이제 기존 미스터리 개체 모두가 pk = 1 인 플레이어를 가리 킵니다. 그러면 관리자 (필요한 경우)에서 변경할 수 있습니다. – stalk

+0

도움을 주셔서 감사합니다. – MaT

+0

답변으로 작성하겠습니다. – stalk

답변

5

또 다른 옵션은 외래 키를 추가하기 전에 data migration을 만들어 특정 ID로 새 Player 인스턴스를 만드는 것입니다. 해당 id가 이전에 데이터베이스에 존재하지 않는지 확인하십시오.

1.Create 데이터 마이그레이션 파일

$ ./manage.py datamigration myapp add_player 
Created 00XX_add_player.py 

2.Edit 전달뒤로 파일의 방법 :

def forwards(self, orm): 
    orm['myapp.Player'].objects.create(name=u'Very misterious player', id=34) 

def backwards(self, orm): 
    # Haven't tested this one yet 
    orm['myapp.Player'].objects.filter(id=34).delete() 

3.Add 당신의 미스터리 클래스에 외래 키 스키마를 다시 이주하십시오. 그것은

$ ./manage.py schemamigration --auto myapp 
? The field 'Mistery.player' does not have a default specified, yet is NOT NULL. 
? Since you are adding this field, you MUST specify a default 
? value to use for existing rows. Would you like to: 
? 1. Quit now, and add a default to the field in models.py 
? 2. Specify a one-off value to use for existing columns now 
? Please select a choice: 2 
? Please enter Python code for your one-off default value. 
? The datetime module is available, so you can do e.g. datetime.date.today() 
>>> 34 
+ Added field player on myapp.Mistery 
Created 0010_auto__add_field_mistery_player.py. You can now apply this migration with: ./manage.py migrate myapp 

(34)가 4.Finally 마이그레이션 명령을 실행,이 예에서, 데이터 마이그레이션 ID에 대한 기본 값을 물어볼 것입니다 그것은 새로운 선수를 삽입하고 모든 업데이트 순서로 마이그레이션을 실행합니다 새로운 플레이어에 대한 참조가있는 미스터리 행.

+4

제발하지 마세요. 이 솔루션은 다른 사람이 이전을 실행할 때 쉽게 앞으로 물지 수 있습니다. 그들이 이미 ID가있는 객체를 가지고 있다면 어떻게 될까요? 일반적으로 임의의 ID를 선택하여 마이그레이션에 넣는 것은 매우 나쁜 관행으로 간주되어야합니다. 제안 된 솔루션을 참조하십시오. – Josh

2

데이터베이스에 미스테리 개체가 이미있는 경우 남은 공백 일 수 없으므로 player 필드에 입력 할 값을 알아야합니다.

한 가지 가능한 솔루션 :

2. Specify a one-off value to use for existing columns now 

을 선택한 다음 1을 입력 그래서 기존 신비의 모든 개체는 지금 PK와 플레이어를 가리 킵니다 = 1. 그럼 당신은 변경할 수 있습니다 (필요한 경우) 관리자 페이지에서.

11

이것은 3 가지 마이그레이션에서 가장 잘 수행됩니다.

1 단계는 새로운 모델을 만들고 플레이어가 null이 될 수 있습니다 : player = models.ForeignKey(Player, null=True)

2 단계../manage.py schemamigration <app> --auto

3 단계 실행 ./manage.py datamigration <app> set_default_players

4 단계 업데이트 앞뒤로 기본 플레이어를 설정 원하는대로 논리를 사용하는 <app>/migrations/<number>_set_default_players.py에서 실행합니다. 모든 Mystery 개체의 값이 player인지 확인하십시오.

단계 5. playernull=False이되도록 Mystery 모델을 업데이트하십시오.

6 단계 실행 ./manage.py schemamigration <app> --auto

단계 데이터베이스가 이미 미스터리 개체가 포함되어있는 경우 ./manage.py migrate <app>

+0

이 답변은 허용 된 것보다 낫습니다. 내가 제안하는 유일한 변경 사항은 "null = True"가 "null = 허용"인 경우 "blank = True"여야한다는 것입니다. (직관적입니까? 아니오.) –

+0

왜 이것을 생각하는지 조금 더 설명해 주시겠습니까? 'blank'는 유효성 검사에만 영향을 미치므로, 필드가 nullable 인 짧은 기간에는 적용하지 말아야합니다. https://docs.djangoproject.com/ko/1.8/ref/models/fields/#blank – Josh

+0

나쁘다. 심하게 깨진 django 문서에 다시 한번 나타납니다. 'null = True'가 맞습니다. –