사람은 실수를 한다.
역시 나는 오늘도 실수를 했다.
Django project에 있었던 user 폴더를 무심코 지워버렸다.
쉽게 설명하자면, 내 웹서비스에서는 유저는 당연히 회원 가입 / 계정 정보 변경 / 계정 삭제 등 계정 관련 업무를 할 수 있어야 한다. 이 기능들을 담은 폴더를 삭제한 것이다.
부랴부랴 다음 command line으로 users application 폴더를 재생성했다.
django-admin startapp users
그러나 서버를 돌려보았더니, 에러가 생겼다.
python manage.py runserver
------------------------------------------------------------------------------------------------------
Watching for file changes with StatReloader
Performing system checks...
System check identified no issues (0 silenced).
Exception in thread django-main-thread:
Traceback (most recent call last):
File "/Users/noopy/.local/share/virtualenvs/django-airbnb-clone-AcLC9Tzu/lib/python3.8/site-packages/django/db/migrations/loader.py", line 166, in check_key
return self.graph.root_nodes(key[0])[0]
IndexError: list index out of range
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/threading.py", line 932, in _bootstrap_inner
self.run()
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "/Users/noopy/.local/share/virtualenvs/django-airbnb-clone-AcLC9Tzu/lib/python3.8/site-packages/django/utils/autoreload.py", line 54, in wrapper
fn(*args, **kwargs)
File "/Users/noopy/.local/share/virtualenvs/django-airbnb-clone-AcLC9Tzu/lib/python3.8/site-packages/django/core/management/commands/runserver.py", line 120, in inner_run
self.check_migrations()
File "/Users/noopy/.local/share/virtualenvs/django-airbnb-clone-AcLC9Tzu/lib/python3.8/site-packages/django/core/management/base.py", line 453, in check_migrations
executor = MigrationExecutor(connections[DEFAULT_DB_ALIAS])
File "/Users/noopy/.local/share/virtualenvs/django-airbnb-clone-AcLC9Tzu/lib/python3.8/site-packages/django/db/migrations/executor.py", line 18, in __init__
self.loader = MigrationLoader(self.connection)
File "/Users/noopy/.local/share/virtualenvs/django-airbnb-clone-AcLC9Tzu/lib/python3.8/site-packages/django/db/migrations/loader.py", line 49, in __init__
self.build_graph()
File "/Users/noopy/.local/share/virtualenvs/django-airbnb-clone-AcLC9Tzu/lib/python3.8/site-packages/django/db/migrations/loader.py", line 227, in build_graph
self.add_external_dependencies(key, migration)
File "/Users/noopy/.local/share/virtualenvs/django-airbnb-clone-AcLC9Tzu/lib/python3.8/site-packages/django/db/migrations/loader.py", line 191, in add_external_dependencies
parent = self.check_key(parent, key[0])
File "/Users/noopy/.local/share/virtualenvs/django-airbnb-clone-AcLC9Tzu/lib/python3.8/site-packages/django/db/migrations/loader.py", line 173, in check_key
raise ValueError("Dependency on app with no migrations: %s" % key[0])
ValueError: Dependency on app with no migrations: users
users 폴더에서 데이터가 migration 이 안 됐다는 것이다.
Migrate이란, 다음과 같다:
- SQL needs to learn how database look like.
- You change the shape of data(=creating migration), and migrate to update database
- Updating Database: Django shapes the data(or change the shape), you create migration, you apply migration
그럼 간단하다. user의 데이터가 아직 데이터베이스에 적용이 안 된 거라면, 데이터를 적용시키면 됐다. 여기까지는 순조로웠다.
python manage.py makemigrations
--------------------------------------------------
Migrations for 'users':
users/migrations/0001_initial.py
- Create model User
하지만 여기서 에러가 터진다. InconsistentMigrationHistory 에러가 생긴다.
python manage.py migrate
-----------------------------------------------------------------------------
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 "/Users/noopy/.local/share/virtualenvs/django-airbnb-clone-AcLC9Tzu/lib/python3.8/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
utility.execute()
File "/Users/noopy/.local/share/virtualenvs/django-airbnb-clone-AcLC9Tzu/lib/python3.8/site-packages/django/core/management/__init__.py", line 375, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/Users/noopy/.local/share/virtualenvs/django-airbnb-clone-AcLC9Tzu/lib/python3.8/site-packages/django/core/management/base.py", line 323, in run_from_argv
self.execute(*args, **cmd_options)
File "/Users/noopy/.local/share/virtualenvs/django-airbnb-clone-AcLC9Tzu/lib/python3.8/site-packages/django/core/management/base.py", line 364, in execute
output = self.handle(*args, **options)
File "/Users/noopy/.local/share/virtualenvs/django-airbnb-clone-AcLC9Tzu/lib/python3.8/site-packages/django/core/management/base.py", line 83, in wrapped
res = handle_func(*args, **kwargs)
File "/Users/noopy/.local/share/virtualenvs/django-airbnb-clone-AcLC9Tzu/lib/python3.8/site-packages/django/core/management/commands/migrate.py", line 90, in handle
executor.loader.check_consistent_history(connection)
File "/Users/noopy/.local/share/virtualenvs/django-airbnb-clone-AcLC9Tzu/lib/python3.8/site-packages/django/db/migrations/loader.py", line 295, in check_consistent_history
raise InconsistentMigrationHistory(
django.db.migrations.exceptions.InconsistentMigrationHistory: Migration admin.0001_initial is applied before its dependency users.0001_initial on database 'default'.
Inconsistent Migration History를 보고, "내가 users 폴더를 중간에 삭제하는 바람에 데이터를 업데이트 하는 게 꼬였구나!"를 깨달았다.
그래서 migration history를 조회했다.
python manage.py showmigrations
------------------------------------------------------
admin
[X] 0001_initial
[X] 0002_logentry_remove_auto_add
[X] 0003_logentry_add_action_flag_choices
auth
[X] 0001_initial
[X] 0002_alter_permission_name_max_length
[X] 0003_alter_user_email_max_length
[X] 0004_alter_user_username_opts
[X] 0005_alter_user_last_login_null
[X] 0006_require_contenttypes_0002
[X] 0007_alter_validators_add_error_messages
[X] 0008_alter_user_username_max_length
[X] 0009_alter_user_last_name_max_length
[X] 0010_alter_group_name_max_length
[X] 0011_update_proxy_permissions
contenttypes
[X] 0001_initial
[X] 0002_remove_content_type_name
sessions
[X] 0001_initial
users
[ ] 0001_initial
저기서 혼자서만 체크박스가 안 되어있는 놈(users 밑의 0001_initial)이 문제를 일으키는 게 분명했다.
아직 각 application에 함수도 입력을 안 했으며, 개발 초창기에 생긴 문제이기 때문에, 극단적인 방법을 쓰기로 했다.
혼자서만 체크박스가 안 되어서 문제라면, 모든 것들의 체크박스를 지워버리자!
Migrating from django user model to a custom user model
I am following these two references (one and two) to have a custom user model in order to authenticate via email and also to add an extra field to it. class User(AbstractBaseUser, PermissionsMixin...
stackoverflow.com
따라서 프로젝트 폴더의 db.sqlite3 파일을 지워서, 아예 migration history 전체를 날려버리기로 했다. 그리고 나서 migration history를 찾아보니, 밑에처럼 체크박스들이 깔-끔해졌다.
python manage.py showmigrations
------------------------------------------------------
admin
[ ] 0001_initial
[ ] 0002_logentry_remove_auto_add
[ ] 0003_logentry_add_action_flag_choices
auth
[ ] 0001_initial
[ ] 0002_alter_permission_name_max_length
[ ] 0003_alter_user_email_max_length
[ ] 0004_alter_user_username_opts
[ ] 0005_alter_user_last_login_null
[ ] 0006_require_contenttypes_0002
[ ] 0007_alter_validators_add_error_messages
[ ] 0008_alter_user_username_max_length
[ ] 0009_alter_user_last_name_max_length
[ ] 0010_alter_group_name_max_length
[ ] 0011_update_proxy_permissions
contenttypes
[ ] 0001_initial
[ ] 0002_remove_content_type_name
sessions
[ ] 0001_initial
users
[ ] 0001_initial
그 이후에 일괄적으로 migration을 시키니, 정상작동했다.
python manage.py migrate
------------------------------------------------------------------------
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions, users
Running migrations:
Applying contenttypes.0001_initial... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0001_initial... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying users.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying sessions.0001_initial... OK
물론 전에 입력한 유저 기록들은 지워졌지만, 개발 초기에 저지른 실수를 빠른 시간 내에 수습해서 만족스럽다.
'Project Based Learning > 운동 추천 웹서비스 - FitCuration' 카테고리의 다른 글
Django 학습 3주일 차 - 몸져눕다 (0) | 2020.03.17 |
---|---|
Django 학습 2주일 차 - Node(Express.js)와의 비교 (0) | 2020.02.29 |
Django 학습 1주일 차 - 어떻게 하면 날로 먹을까? (0) | 2020.02.22 |
인스타그램 텍스트 데이터로 나에게 맞는 운동을 찾는 법: TF-IDF, Word2Vec (0) | 2020.02.03 |
Notion API 사용 후기 & HTML 파일 구하기 (0) | 2020.01.24 |