IT

파이썬 관계필드(Foreingkey) 마이그레이션 방법

bepuri 2020. 11. 26. 10:35
728x90
Traceback (most recent call last):
  File ".\manage.py", line 21, in <module>
    main()
  File ".\manage.py", line 17, in main
    execute_from_command_line(sys.argv)
  File "C:\Users\Administrator\project\djangovenv\lib\site-packages\django\core\management\__init__.py", line 401, in execute_from_command_line
    utility.execute()
  File "C:\Users\Administrator\project\djangovenv\lib\site-packages\django\core\management\__init__.py", line 395, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "C:\Users\Administrator\project\djangovenv\lib\site-packages\django\core\management\base.py", line 328, in run_from_argv  
    self.execute(*args, **cmd_options)
  File "C:\Users\Administrator\project\djangovenv\lib\site-packages\django\core\management\base.py", line 369, in execute        
    output = self.handle(*args, **options)
  File "C:\Users\Administrator\project\djangovenv\lib\site-packages\django\core\management\base.py", line 83, in wrapped
    res = handle_func(*args, **kwargs)
  File "C:\Users\Administrator\project\djangovenv\lib\site-packages\django\core\management\commands\migrate.py", line 231, in handle
    post_migrate_state = executor.migrate(
  File "C:\Users\Administrator\project\djangovenv\lib\site-packages\django\db\migrations\executor.py", line 117, in migrate      
    state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial)
  File "C:\Users\Administrator\project\djangovenv\lib\site-packages\django\db\migrations\executor.py", line 147, in _migrate_all_forwards
    state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
  File "C:\Users\Administrator\project\djangovenv\lib\site-packages\django\db\migrations\executor.py", line 245, in apply_migration
    state = migration.apply(state, schema_editor)
  File "C:\Users\Administrator\project\djangovenv\lib\site-packages\django\db\migrations\migration.py", line 124, in apply       
    operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
  File "C:\Users\Administrator\project\djangovenv\lib\site-packages\django\db\migrations\operations\fields.py", line 249, in database_forwards
    schema_editor.alter_field(from_model, from_field, to_field)
  File "C:\Users\Administrator\project\djangovenv\lib\site-packages\django\db\backends\sqlite3\schema.py", line 138, in alter_field
    super().alter_field(model, old_field, new_field, strict=strict)
  File "C:\Users\Administrator\project\djangovenv\lib\site-packages\django\db\backends\base\schema.py", line 564, in alter_field
    self._alter_field(model, old_field, new_field, old_type, new_type,
  File "C:\Users\Administrator\project\djangovenv\lib\site-packages\django\db\backends\sqlite3\schema.py", line 360, in _alter_field
    self._remake_table(model, alter_field=(old_field, new_field))
  File "C:\Users\Administrator\project\djangovenv\lib\site-packages\django\db\backends\sqlite3\schema.py", line 283, in _remake_table
    self.execute("INSERT INTO %s (%s) SELECT %s FROM %s" % (
  File "C:\Users\Administrator\project\djangovenv\lib\site-packages\django\db\backends\base\schema.py", line 142, in execute     
    cursor.execute(sql, params)
  File "C:\Users\Administrator\project\djangovenv\lib\site-packages\django\db\backends\utils.py", line 100, in execute
    return super().execute(sql, params)
  File "C:\Users\Administrator\project\djangovenv\lib\site-packages\django\db\backends\utils.py", line 68, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "C:\Users\Administrator\project\djangovenv\lib\site-packages\django\db\backends\utils.py", line 77, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "C:\Users\Administrator\project\djangovenv\lib\site-packages\django\db\backends\utils.py", line 86, in _execute
    return self.cursor.execute(sql, params)
  File "C:\Users\Administrator\project\djangovenv\lib\site-packages\django\db\utils.py", line 90, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "C:\Users\Administrator\project\djangovenv\lib\site-packages\django\db\backends\utils.py", line 86, in _execute
    return self.cursor.execute(sql, params)
  File "C:\Users\Administrator\project\djangovenv\lib\site-packages\django\db\backends\sqlite3\base.py", line 396, in execute    
    return Database.Cursor.execute(self, query, params)
django.db.utils.IntegrityError: UNIQUE constraint failed: new__papers_paper.status_id

이미 디비 migration이 끝났고, 데이터 삽입까지 이뤄진 상황에서 관계형 필드를 추가하려고하면 위와같은 에러를 뜬다. 말그대로 무결성 에러인데 status_id가 없어서 일어나는 일이다.

 

당연히 FK 필드 추가를 하는데 연결할 id를 모르니 에러가 뜰 수 밖에 없다.

 

그 경우 수동으로 작업을 해줘야하는데,

coderbook.com/@marcus/add-new-non-null-foreign-key-to-existing-django-model/

 

위 자료를 참고하서 작업해서 해결했다.

마이그레이션 작업할 때 FK로 연결할 모델의 데이터를 생성후 연결 해주는 함수를 하나만들어주면 된다.

이거 모를땐 귀찮아서 DB를 지우고 다시 시작했는데, 진작 이렇게 할걸 하는 생각이 든다.

 

RunPython 하는 코드는 operation 제일 마지막에 넣어주면되고, get_or_create는 FK일때 그렇게 사용하고 OneToOne으로 쓸때는 create 해줘야한다. 아니면 유일성 에러가 발생하게된다.

728x90

'IT' 카테고리의 다른 글

django-multiselectfield post request  (0) 2020.12.01
html a4 사이즈로 인쇄.  (0) 2020.12.01
워드 메모 없이 인쇄.  (0) 2020.11.25
The way to extend vee-validate custom rules.  (0) 2020.11.19
ValidationProvider required_if  (3) 2020.11.19