기존에 웹하드 기능을 운영 중이었는데, 서버 DB를 여러 번 초기화하는 과정에서 기존 미디어 폴더에 현재는 사용되지 않는 파일들이 남아 있었다. 새롭게 DB를 초기화한 후 업로드를 하면 기존의 업로드 내역은 사라지고(실제 미디어 디렉토리에는 파일이 남아 있지만), 초기화 이후부터 업로드 리스트가 새롭게 쌓였다. 이를 해결하기 위해 django/webhard/management/commands/import_existing_files.py
를 만들어 실행했었다.
이번에도 사이트 도메인을 변경하면서 다시 DB를 처음부터 작업하게 되었고, 같은 과정을 반복하게 되었다. 하지만 웹하드 디렉토리 내의 파일들을 몽고DB에 그대로 등록하는 과정에서 업로드 날짜가 import_existing_files.py
실행 시간으로 저장되는 문제가 발생했다. 이 부분이 마음에 들지 않아 수정하는 과정에서 몇 가지 사실을 알게 되었다.
Django ORM을 통해 import_existing_files.py
를 작성했는데, Django 모델의 필드 옵션에 따라 자동으로 데이터가 검증되고 저장되는 방식이 결정된다. 특히, auto_now=True
옵션이 적용된 필드는 우리가 지정한 값을 무시하고 현재 시간으로 덮어쓴다는 점이 문제였다. 여러 시행착오 끝에, Pymongo를 사용하여 데이터를 직접 삽입하는 방식으로 해결할 수 있었다.
Django ORM과 Pymongo의 차이점
- Django ORM
- Django 모델의 필드 정의에 따라 데이터가 검증 및 자동 수정될 수 있다.
auto_now=True
와 같은 옵션이 있으면 원하는 값이 덮어씌워질 가능성이 있다.- ORM의 자동화된 처리를 따르기 때문에, 특정한 값(예: 파일의 원래 생성 시간)을 정확히 유지하기 어려울 수 있다.
- Pymongo
- 중간 처리 없이 우리가 지정한 값을 그대로 저장한다.
- Django 모델의 필드 옵션에 영향을 받지 않는다.
- Django ORM을 우회하여 직접 값을 삽입하면, 파일의 원래 생성 시간을 정확하게 DB에 반영할 수 있다.
Django ORM의 종류와 Djongo의 역할
Django ORM은 기본적으로 관계형 데이터베이스(RDBMS)를 대상으로 동작하는 객체-관계 매핑(Object-Relational Mapping) 도구이다. 대표적으로 지원하는 데이터베이스 엔진은 다음과 같다:
- PostgreSQL (가장 강력한 지원, 많은 확장 기능 제공)
- MySQL
- SQLite (기본 내장, 테스트 및 소규모 프로젝트에 적합)
- MariaDB
- Oracle
Django ORM은 SQL 쿼리를 추상화하여 Python 코드로 데이터베이스를 조작할 수 있도록 해준다.
NoSQL을 위한 ORM 또는 대체 라이브러리
Django 기본 ORM은 NoSQL을 직접 지원하지 않지만, 몇 가지 서드파티 라이브러리를 통해 가능하게 만들 수 있다.
- Djongo (MongoDB 지원)
- Djongo는 Django ORM을 MongoDB에서 사용할 수 있도록 해주는 라이브러리이다.
- Django의 모델을 그대로 사용하면서 MongoDB를 백엔드로 활용할 수 있다.
- 하지만 Django ORM의 모든 기능을 완벽하게 지원하는 것은 아니며, 일부 기능에는 제한이 있을 수 있다.
- MongoEngine (ODM: Object-Document Mapping)
- Django ORM과는 다르게, MongoDB의 문서(Document) 기반 데이터 모델을 사용한다.
- Django ORM과 완전히 다른 방식으로 동작하며, Django의 모델 클래스를 직접 사용하지 않는다.
- 하지만 Django와의 통합을 위해
django-mongoengine
같은 패키지를 사용할 수 있다.
- Tortoise ORM (비동기 지원)
- Django ORM을 기반으로 하지 않지만, 비동기(Async) 방식의 ORM이다.
- 주로 FastAPI, Starlette, Sanic 같은 비동기 프레임워크와 함께 사용된다.
- 관계형 데이터베이스뿐만 아니라 일부 NoSQL도 지원하는 방향으로 개발되고 있다.
Djongo는 ORM인가?
Djongo는 Django ORM을 MongoDB에서 작동할 수 있도록 만든 브릿지 라이브러리로 볼 수 있다. 따라서 Django ORM의 기능을 일부 확장한 것으로 볼 수 있지만, 전통적인 ORM이라고 보기에는 애매한 점이 있다. MongoDB는 SQL이 아닌 NoSQL 방식(문서 기반)으로 동작하기 때문에, Django ORM이 제공하는 기능 중 일부는 Djongo에서 완벽하게 지원되지 않을 수 있다.
결론 1: Django ORM과 Pymongo
Django ORM은 관계형 데이터베이스에 최적화된 도구이며, 자동화 기능을 제공하지만 특정 필드 값(예: 원본 업로드 시간)을 유지하려면 자동 처리를 우회해야 한다. 따라서 미디어 파일을 DB에 등록하는 과정에서 정확한 시간 정보를 유지하고 싶다면, Django ORM 대신 Pymongo를 활용하여 직접 데이터를 삽입하는 것이 더 적절한 방법일 수 있다.
결론 2: Djongo와 Django ORM
Django ORM은 관계형 데이터베이스에 최적화된 도구이지만, NoSQL을 사용할 때는 Djongo나 MongoEngine 같은 서드파티 라이브러리를 활용할 수 있다. 특히 MongoDB를 사용할 때 Django ORM을 유지하고 싶다면 Djongo를 사용할 수 있지만, 완벽한 호환성을 원한다면 MongoEngine 같은 대체 라이브러리를 고려하는 것이 좋다.