티스토리 뷰

결론은 맨 마지막

데이터베이스 이전

테스트 서버(A)에 실제 데이터로 구현할 것이 있어서 실제 서버(B) 데이터베이스의 일부 데이터를 옮기려고 한다.

B->A로 데이터를 옮기는 작업이다.


django에서는 dumpdata와 loaddata라는 명령어를 지원해주기에, sql로 접속하여 일일이 데이터를 백업할 필요가 없다.


간단하게는 다음과 같다.


(B서버)$ python manage.py dumpdata > db.json

(A서버)$ python manage.py loaddata db.json


' > db.json'은 db.json이라는 이름으로 백업파일을 만든다는 것이다.

생략하면 default 이름으로 파일이 생긴다.


그런데 그냥 이렇게 하면 에러가 발생한다.


contenttype 에러

첫 번째 에러는 content type과 관련된 에러인데, 이 에러는 content type을 가져오지 않으면 해결된다.
즉 dumpdata를 할 때 exclude 하면 된다.
(B서버)$ python manage.py dumpdata --exclude contenttypes > db.json

조금 다른 형식으로 써도 된다.

-e contenttypes 나 --exclude=contenttypes 도 되는 것 같다.


하지만 이래도 나는 에러가 난다.


foreign key 에러

이번 에러는 foreign key와 관련된 에러인데, foreign key를 사용한 앱이라면 발생할만 하다.
예를 들어, foreign key를 사용하면 db에는 가져올 값의 id(primary key)를 저장하는데, 이렇게 되면 id가 변하는 순간 제대로된 foreign key를 가져오지 못하는 것이다.
B서버에 user1의 id값이 1인데, A서버에서 id값이 1이 아닌 경우에 발생하는 것이다.
그래서 django에서는 natural이라는 기능을 지원한다.

(B서버)$ python manage.py dumpdata --natural-foreign --exclude contenttypes > db.json


추가 명령어

이외에도 에러가 발생하거나 쓸데없는 데이터까지 모두 가져오는 경우가 있다.
그래서 아래의 명령어를 추천한다.
(B서버)$ python manage.py dumpdata --natural-foreign --natural-primary --exclude contenttypes --exclude auth.permission --exclude admin.logentry --exclude sessions.session --indent 4 > db.json

--natural-primary는 pk값이 필요 없는 것들의 pk값을 가져오지 않는다.

혹시나 pk 값 충돌이 발생하면 이걸 쓰면 좋다.


permission, session, logentry는 보통 이전하는 서버에서는 필요없는 데이터인데 용량이 많아서 빼도 될 것 같다.


--indent 4는 사람이 읽기 편하도록 json파일을 만드는 것이다.

json파일을 들여다볼 일이 없다면 안써도 되지만, 나는 에러가 너무 많이 나서 json파일을 들여다볼 필요가 있었다.


duplicate key 에러

나는 여기에 추가적인 에러가 계속 발생해서 애를 먹었다.
sql에서 integrity에러가 발생했는데, 중복된 key값이라면서 loaddata가 안됐다.
알고보니 이것도 pk값과 관련된 에러였다.

나는 user model을 django의 기본 auth.user 모델에 profile 모델을 one-to-one으로 확장해서 사용했다.

이게 문제였다.
json 파일에서 profile 부분을 제거하고 loaddata를 하니, 데이터가 잘 이전됐다.
물론 profile 부분은 다 제거됐다.
난 그걸로도 충분했다.

정리

(B서버)$ python manage.py dumpdata --natural-foreign --natural-primary --exclude contenttypes --exclude auth.permission --exclude admin.logentry --exclude sessions.session --indent 4 > db.json

(A서버)$ python manage.py loaddata db.json


model을 확장한 경우, 확장된 데이터를 지우고 load.

확장된 데이터는 따로 나중에 load해야 함. (그 방법은 안 해봄)

댓글