기본값없이 사용자 프로필에 nullable이 아닌 필드 'new_field'를 추가하려고합니다.


108

Django 1.7부터 South 또는 다른 마이그레이션 시스템을 사용할 필요가 없다는 것을 알고 있으므로 간단한 명령을 사용하고 있습니다. python manage.py makemigrations

그러나 내가 얻는 것은이 오류입니다.

You are trying to add a non-nullable field 'new_field' to userprofile without a default;
we can't do that (the database needs something to populate existing rows).

다음은 models.py입니다.

class UserProfile(models.Model):
    user = models.OneToOneField(User)
    website = models.URLField(blank=True)
    new_field = models.CharField(max_length=140)

옵션은 무엇입니까?


3
새 테이블을 만들 때가 아니라 기존 테이블을 변경할 때 문제가 발생한다고 덧붙이고 싶었습니다.
x-yuri

답변:


91

기본값을 제공해야합니다.

new_field = models.CharField(max_length=140, default='SOME STRING')

new_field에 웹 사이트 필드의 사본이 필요하면 어떻게하나요? 어떻게 보일까요? default = website하지 않습니다
Irmantas Želionis 2014-10-03

7
먼저 가짜 기본값으로 마이그레이션을 수행 한 다음 데이터 마이그레이션 을 생성하여 각 레코드를 반복 new_field하고 website.
dgel 2014-10-03

CharField의 기본값은 선택 사항이어야합니다.
Florent

87

만약 는 초기 개발주기에 있고 상관 없어 현재에 대한 데이터베이스 데이터 당신은 그것을 제거하고 마이그레이션 할 수 있습니다. 하지만 먼저 마이그레이션 디렉터리를 정리하고 테이블 (django_migrations)에서 해당 행을 제거해야합니다.

rm  your_app/migrations/*

rm db.sqlite3
python manage.py makemigrations
python manage.py migrate

8
하나 더. 마이그레이션 테이블을 정리해야합니다. 예 :mysql -u[user] [database] -e "delete from django_migrations where app=[your_app]"
helpse dec

이게 방법이야. Django는 마이그레이션 및 모델 감지 등을 짜증나게 생각합니다. 이에 대한 주요 업데이트를 원합니다.
WesternGun

마이그레이션에서 모든 파일을 삭제하고 django_migrations에서 모든 행을 삭제했으며 이제 실행할 때 "django.db.migrations.exceptions.NodeNotFoundError : Migration stories.0001_initial dependencies reference nonexistent parent node ( 'sources', '0002_auto_20180903_1224')"가 표시됩니다. 이주.
brainLoop

1
또한 __init__.py 마이그레이션에서를 삭제하지 않거나 나중에 복원하십시오. 그렇지 않으면 makemigration이 작동하지 않습니다. stackoverflow.com/a/46362750/1649917
nmu

python manage.py sqlmigrate name_of_your_app nb_of_the_migration필요합니다
zar3bski

37

한 가지 옵션은 'new_field'에 대한 기본값을 선언하는 것입니다.

new_field = models.CharField(max_length=140, default='DEFAULT VALUE')

또 다른 옵션은 'new_field'를 nullable 필드로 선언하는 것입니다.

new_field = models.CharField(max_length=140, null=True)

'new_field'를 nullable 필드로 허용하기로 결정한 경우 'new_field'에 대한 유효한 입력으로 '입력 없음'을 허용 할 수 있습니다. 그런 다음 blank=True문도 추가해야 합니다.

new_field = models.CharField(max_length=140, blank=True, null=True)

심지어와 null=True및 / 또는blank=True 필요한 경우에는 기본 값을 추가 할 수 있습니다 :

new_field = models.CharField(max_length=140, default='DEFAULT VALUE', blank=True, null=True)

7
«CharField 및 TextField와 같은 문자열 기반 필드에 null을 사용하지 마십시오. 문자열 기반 필드에 null = True가 있으면 "데이터 없음"에 대해 두 가지 가능한 값 (NULL 및 빈 문자열)이 있음을 의미합니다.» - 모델 필드 참조
CHEMA

7

개발주기의 초기 단계라면 이것을 시도해 볼 수 있습니다.

해당 모델과 모든 사용법을 제거 / 주석하십시오. 마이그레이션을 적용합니다. 그러면 해당 모델이 삭제되고 모델이 다시 추가되고 마이그레이션이 실행되고 새 필드가 추가 된 깨끗한 모델이 생성됩니다.


그리고 여기에 설명 된대로 django_migrations 마이그레이션 테이블을 정리하십시오. stackoverflow.com/questions/26185687/… 또는 GUI를 사용하고 필요한 행을 삭제하십시오.
RusI

4

"웹 사이트"가 다음보다 비어있을 수있는 경우 new_field 것으로 설정해야합니다.

이제 new_field"웹 사이트"에서 값을 가져 오기 위해 비어 있는 경우 저장에 논리를 추가 하려면 다음 Model과 같이 저장 기능을 재정의 하면됩니다.

class UserProfile(models.Model):
    user = models.OneToOneField(User)
    website = models.URLField(blank=True, default='DEFAULT VALUE')
    new_field = models.CharField(max_length=140, blank=True, default='DEFAULT VALUE')

    def save(self, *args, **kwargs):
        if not self.new_field:
            # Setting the value of new_field with website's value
            self.new_field = self.website

        # Saving the object with the default save() function
        super(UserProfile, self).save(*args, **kwargs)

4

누구나를 설정하는 경우 ForeignKey기본값을 설정하지 않고 nullable 필드 만 허용 할 수 있습니다.

new_field = models.ForeignKey(model, null=True)

데이터베이스에 이미 데이터가 저장된 경우 기본값을 설정할 수도 있습니다.

new_field = models.ForeignKey(model, default=<existing model id here>)

3

내부에 이미 데이터가있는 테이블에 대한 참조를 추가 할 수 없습니다.
변화:

user = models.OneToOneField(User)

에:

user = models.OneToOneField(User, default = "")

하다:

python manage.py makemigrations
python manage.py migrate

다시 변경 :

user = models.OneToOneField(User)

다시 마이그레이션하십시오.

python manage.py makemigrations
python manage.py migrate

2

new_file에서 부울 속성 null을 추가하십시오.

new_field = models.CharField(max_length=140, null=True)

a ./manage.py syncdb를 실행 한 후 DB를 새로 고칩니다. 그리고 마침내 당신은 실행 ./manage.py makemigrations 하고./manage.py migrate



2

테이블에 이미 데이터베이스 항목이 UserProfile있습니까? 그렇다면 새 열을 추가 할 때 DB는 NULL. 따라서 열의 해당 필드를 무엇으로 설정할 것인지 묻습니다 new_fields. 문제를 해결하기 위해이 테이블에서 모든 행 을 삭제 해야했습니다.

(이것이 얼마 전에 대답되었다는 것을 알고 있지만, 방금이 문제에 부딪 쳤고 이것이 내 해결책이었습니다. 바라건대 이것을 보는 새로운 사람에게 도움이되기를 바랍니다)


1
나는 테이블에 행을 삽입하지 않았고 여전히 이것을 얻습니다. Tomasz가 제안한대로 모델을 변경하려면 모든 마이그레이션 기록을 삭제하고 마이그레이션 테이블을 지워야합니다.
WesternGun

1

솔직히이 문제를 해결하는 가장 좋은 방법은 필요한 모든 필드와 약간 다른 이름을 가진 다른 모델을 만드는 것입니다. 마이그레이션을 실행하십시오. 사용하지 않는 모델을 삭제하고 마이그레이션을 다시 실행하십시오. 짜잔.


1

문제가되는 모델의 테이블을 잘라도 괜찮다 None면 프롬프트에서 일회성 기본값을 지정할 수 있습니다 . default=None코드에 기본값이없는 동안 마이그레이션은 불필요 합니다. 더 이상 기본값이 필요한 데이터가 테이블에 없기 때문에 잘 적용될 수 있습니다.


1

저는 개발주기의 초기 였기 때문에 모든 사람에게 효과가 없을 수도 있습니다 (하지만 왜 그렇게되지 않을지는 모르겠습니다).

blank=True, null=True오류가 발생한 열에 추가 했습니다. 그런 다음 python manage.py makemigrations명령을 실행했습니다 .

이 명령을 실행 한 직후 (및 실행하기 전에 python manage.py migrate) blank=True, null=True모든 열에서을 제거했습니다 . 그리고 나는 달렸다python manage.py makemigrations 다시 습니다. 내가 선택한 열을 직접 변경할 수있는 옵션이 주어졌습니다.

그런 다음 나는 달렸고 python manage.py migrate모든 것이 잘 작동했습니다!


0

Django가 실제로 말하는 것은 다음과 같습니다.

Userprofile 테이블에 데이터가 있고 new_fieldnull 인 값 이있을 수 있지만 모르겠습니다. 따라서 속성을 nullable이 아닌 것으로 표시하고 싶습니까? NULL 값이 있으면 오류가 발생할 수 있기 때문입니다.

userprofile테이블 의 값 이 NULL이 아니라고 확신하는 경우 -해제되고 경고를 무시하십시오.

이러한 경우에 가장 좋은 방법은 옵션 2에 명시된대로 빈 값을 처리하기 위해 RunPython 마이그레이션을 만드는 것입니다.

2) 지금은 무시하고 NULL로 기존 행을 직접 처리하도록합니다 (예 : 이전 데이터 마이그레이션에서 NULL 값을 처리하기 위해 RunPython 또는 RunSQL 작업을 추가했기 때문).

RunPython 마이그레이션에서 값 UserProfile이 비어 있는 모든 인스턴스 를 찾아 new_field거기에 올바른 값을 입력해야합니다 (또는 Django가 모델에서 설정하도록 요구하는 기본값). 다음과 같은 내용이 표시됩니다.

# please keep in mind that new_value can be an empty string. You decide whether it is a correct value.
for profile in UserProfile.objects.filter(new_value__isnull=True).iterator():
    profile.new_value = calculate_value(profile)
    profile.save() # better to use batch save

즐기세요!


문서에서 이것이 어디에 쓰여 있는지 찾을 수없는 것 같습니다. 링크를 게시 해 주시겠습니까
Cody

0

models.py에서

class UserProfile(models.Model): user = models.OneToOneField(User) website = models.URLField(blank=True) new_field = models.CharField(max_length=140, default="some_value")

기본값으로 일부 값을 추가해야합니다.


-1

SSH가 2 가지 옵션을 제공하는 경우 1 번을 선택하고 "없음"을 입력합니다. 그냥 ... 잠시만 요.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.