이 두 가지 오류로 인해 22%의 Django 웹 사이트가 prod를 롤백할 수 없습니다.

Django Doctor 코드를 검토하고 Django 역모드를 자동으로 수정합니다.666개의 Django 프로젝트에서 롤백할 수 없는 마이그레이션이 있는지 확인하였으며, 22%의 Django 코드 인벤토리가 다음과 같은 문제점에 대해 놀라운 반응을 보였습니다.
  • 데이터 마이그레이션에 역방향 프로세서가 없습니다. 마이그레이션에는 데이터를 업데이트하는 프로세서가 있지만 변경 사항을 취소하는 데 사용되지 않습니다.Read more
  • 데이터 이전 가져오기'열'모델: 이전은 코드 라이브러리에서 모델을 가져오는 것이지 실행하는 것이 아니다apps.get_model(...).Read more
  • 이것들은 모두 재난 복구를 막을 것이다.지금 밤 11시인데 생산이 멈췄다고 상상해 보세요.피곤하고 스트레스가 많으며 선택이 없으니 이전 버전으로 돌아가기로 했다.데이터베이스 이전을 반전시킨 다음에 배치하고...잠깐만, 뭐야?
    $ python manage.py migrate hounds 0002
    Unapplying hounds.0003_auto...
    Traceback (most recent call last):
    django.db.migrations.exceptions.IrreversibleError:
    Operation <RunPython > in hounds.0003_auto is not reversible
    
    이것은 이전 좋은 버전으로 돌아가는 것을 막을 것입니다. 데이터베이스 상태가 이전 좋은 코드와 동기화되지 않기 때문입니다. 만약 이전 코드로 돌아가는 것을 시도한다면 데이터베이스 상태는 이전 코드 라이브러리와 호환되지 않습니다.

    1. 역방향 마이그레이션 없음


    Django 데이터 이전은 두 가지 측면이 있는데 그것이 바로 앞쪽과 뒤쪽이다. 그러나 기본적으로 Django가 생성한 골격 데이터 이전은 앞쪽 처리 프로그램만 표시하기 때문에 5분의 1의 Django 코드 라이브러리는 최소한 하나의 이전이 이전 취소를 지원하지 않는다.
    def forwards(apps, schema_editor): 
        ...
    
    class Migration(migrations.Migration):
        dependencies = [("cases", "0009_auto_20200320_1210")]
        operations = [migrations.RunPython(forwards)]
    
    불행하게도, 이전 취소를 시도할 때, 하나만 부족하면 모든 이전이 실패할 수 있다.코드 심사 기간의 인위적인 오류는 이러한 사실을 설명할 수 있다. 즉, 많은 Django 코드 라이브러리는 생산 재난에서 복구할 수 없다. 만약에 100%의 코드 심사원이 100%의 시간 안에 100%의 오류를 발견한다면 우리는 처음부터 코드 심사를 필요로 하지 않는다. 왜냐하면 이런 bermensch는 처음부터 오류를 범하지 않기 때문이다.
    Django 데이터 마이그레이션은 앞으로 이동하지만 뒤로 이동하는 것은 기술적으로 옵션입니다.비록 위의 견해는 정확하지만, 아래의 견해는 훨씬 좋다.
    def forwards(apps, schema_editor): 
        ...
    
    def backwards(apps, schema_editor):
        ...
    
    class Migration(migrations.Migration):
        dependencies = [("cases", "0009_auto_20200320_1210")]
        operations = [migrations.RunPython(forwards, backwards)]
    
    그래서 기술적으로 후퇴는 선택할 수 있다. 스카이다이빙을 할 때 낙하산을 가지고 가는 것이 선택할 수 있는 것처럼 충분한 시간만 있으면 착지할 수 있다.사실 당신이 제작 사이트를 롤백하고 싶다면, 아니, 후퇴는 선택할 수 있는 것이 아니다.'뒤로'를 생략하면 rolling forwards만 선택할 수 있다는 것을 의미합니다. 우리가 알고 있는 유효한 버전으로 안전하게 돌아가는 것보다 특히 스트레스 상태에서 재난 복구를 실행할 때 두려울 뿐입니다.사실 평온한 코드 심사 과정에서 오류가 발생할 수 있다면 압력에 의해 오류가 발생하는 범위를 상상해 보세요.
    복구 방법도 간단하다. 지정reverse만 하면 충분하다.말 그대로 Django는 do nothing를 반대로 하고 데이터 이전을 건너뛰고 던지지 않는다migrations.RunPython.noop:
    class Migration(migrations.Migration):
        dependencies = [("cases", "0009_auto_20200320_1210")]
        operations = [migrations.RunPython(forwards, migrations.RunPython.noop)]
    
    따라서 실천 과정에서 다음과 같은 건의를 따른다.

    🦊 너는 enable Django Doctor 너의 GitHub 환매 협의에서 이 문제를 100% 방지할 수 있다.

    핫 모델 가져오기


    자고의 이전 문제를 볼 수 있습니까?
    from django.db import migrations
    from territory import models
    
    def forwards(apps, schema_editor):
        for item in in models.ChickenCoopLocations.objects.all():
            item.has_chickens = does_have_chickens(item.pk)
            item.save()
    
    class Migration(migrations.Migration):
        dependencies = [("cases", "0005_auto_does_have_chickens.py")]
        operations = [migrations.RunPython(forwards)]
    
    
    def does_have_chickens(pk):
        ...
    
    
    모델에서 직접 가져옵니다.피야.만약 충분한 시간과 충분한 코드 변경이 있다면, 이것은 최종적으로 이동을 깨뜨릴 것이다. 왜냐하면 코드는 데이터 이동을 생성할 때 데이터베이스의 역사 상태가 다르기 때문이다.

    부조화


    DjangoIrreversibleError의 필드는 데이터베이스의 패턴과 일치해야 합니다.Django가 데이터베이스 읽기나 쓰기 작업을 수행할 때 models.py 의 모델 모양을 사용하여 models.pySELECT 필드를 정합니다.INSERT에 데이터베이스 구조에 포함되지 않은 필드가 포함되어 있으면 데이터베이스에서 오류가 발생합니다.
    만약 급하게 코드를 검사한다면, 이 점을 무시하기 쉽다. models.py 실행할 때 이 오류가 발생하지 않기 때문이다.사실 그때0006_populate_has_chickens는 패턴과 일치했지만 일주일 후에 팀원들이 models.py에 새 필드를 추가할 때 무슨 일이 일어날까요?그때부터 ChickenCoopLocations 를 실행할 때마다 0006_populate_has_chickens 데이터베이스 모델에 없는 필드가 있기 때문에 이전은 실패할 것이다.모든 이전이 0에서 시작되었을 때, 예를 들어 CI에서 새로운 개발자가 팀에 가입했을 때, 또는 조립된 노트북을 교체했을 때, 새로운 데이터베이스를 설정할 때 이런 상황이 발생한다.

    미래의 증명

    models.py에서 가장 좋은 것은 0006_populate_has_chickens.py이다. Django가 간소화된 시간 여행 모델을 구축하도록 요구한다. 이 모델의 필드는 데이터베이스에 있는 필드를 반영한다. apps.get_model와 모델이 매우 일치하지 않더라도:
    # 0006_populate_has_chickens.py
    from django.db import migrations
    
    def forwards(apps, schema_editor):
        ChickenCoopLocations = apps.get_model("territory", "ChickenCoopLocations")
        for item in in ChickenCoopLocations.objects.all():
            item.has_chickens = does_have_chickens(item.pk)
            item.save()
    
    class Migration(migrations.Migration):
        dependencies = [("cases", "0005_auto_foo.py")]
        operations = [migrations.RunPython(forwards)]
    
    def does_have_chickens(pk):
        ...
    
    따라서 이전 과정에서 모델을 직접 가져오는 것은 신뢰할 수 없다. 몇 번의 이전 과정에서 시간이 실패할 수 있다. 왜냐하면 이전 과정에서 모델의 코드를 잃어버리기 때문이다.py와 데이터베이스 모델이 일치하지 않습니다. 필요한 이전이 실행되지 않았기 때문에 models.py 데이터베이스에 존재하지 않는 필드를 정의할 수 있습니다.

    Django 코드가 재해 복구를 차단합니까?


    시간의 추이에 따라 과학 기술 채무는 너의 코드 라이브러리에 쉽게 빠져들게 된다.django.doctor 또는 review your GitHub PRs를 통해 확인할 수 있습니다.

    아니면 해봐Django refactoring challenges.

    좋은 웹페이지 즐겨찾기