2020년 3월 10일 화요일

[Django] no such table: main.auth_user__old

해당 오류는 SQLite 3.26.0에서 ALTER TABLE RENAME 구문에 대한 사양 변경으로 발생한 오류라고 한다. 기존의 모델(models.py) 또는 어드민(admin.py)을 수정하는 과정에서 이 오류가 발생할 수 있다. 오류는 Django 2.1.5 이하 버전에서 발생하며 Django의 버전을 2.1.5 이상으로 올린뒤 다시 마이그레이션(makemigrations, migrate) 명령을 호출해주면 문제는 해결된다. 사용하는 버전에 따라 SQLite를 다시 설치해야 하는 경우도 있다고 하는데 내 경우엔 필요한 작업이 아니었기 때문에 확실한 정보는 아니다.

어쨌든 조치를 하기 전에 데이터 백업은 필수.

참고로 contrib.auth.views.login(), logout() 함수는 Django 2.1에서 삭제되었으므로 해당 함수를 사용하는 Django 버전을 쓴다면 LoginView.as_view(template_name='...') 방식으로 수정이 필요하다.

//

위와 같이 작업한 후 마이그레이션은 되었는데, 다시 사용자 데이터를 수정할 때 동일한 문제가 생긴다면 직접 db.sqlite3에 접속해 문제를 해결하는 방법이 있다. (기존 DB를 날리고 새 DB 파일을 생성하는 건 차마 못하겠다..)

커맨드 라인에서 Django 프로젝트 폴더로 이동해 sqlite3 db.sqlite3를 입력하면 Django가 바라보는 SQLite DB에 접근할 수 있다.

테이블 목록을 확인하는 명령어는 .tables 인데 입력해보면
사용자 데이터는 auth_user
그룹 데이터는 auth_group
사용자와 그룹에 대한 관계 데이터는 auth_user_groups
에 저장되어 있는 것을 확인할 수 있다.

수정하고 싶은 데이터의 ID를 알아내 스키마에 맞게 SQL을 작성하면 원하는 작업을 할 수 있는 것이다.

문제가 되는(?) auth_user_groups의 테이블 생성 구문을 살펴보면 아래와 같이 user_id 컬럼이 존재하지 않는 auth_user__old 테이블의 id를 참조하고 있는 것으로 확인된다.

CREATE TABLE "auth_user_groups" (
"id" integer NOT NULL,
"user_id" integer NOT NULL,
"group_id" integer NOT NULL,
PRIMARY KEY("id" AUTOINCREMENT),
FOREIGN KEY("group_id") REFERENCES "auth_group"("id"),
FOREIGN KEY("user_id") REFERENCES "auth_user__old"("id")
);

아마도. 다른 트러블 슈팅 문서대로 조치하였는데 고쳐지지 않는다면 이 부분을 해결하면 될 것이다. 방법은 아래와 같이 외래키가 올바르게 지정된 테이블을 생성한 뒤 교체해 주는 작업을 진행하면 된다.

PRAGMA foreign_keys = OFF;

CREATE TABLE auth_user_groups_temp (
    "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, 
    "user_id" integer NOT NULL REFERENCES "auth_user" ("id"), 
    "group_id" integer NOT NULL REFERENCES "auth_group" ("id")
);

INSERT INTO auth_user_groups_temp SELECT * FROM auth_user_groups;

DROP TABLE auth_user_groups;

ALTER TABLE auth_user_groups_temp RENAME TO auth_user_groups;

PRAGMA foreign_keys = ON;


댓글 없음:

댓글 쓰기