기존에 MongoEngine을 사용할 때 Embedded와 Reference방식에 대한 비교를 진행하는 글을 포스팅 했었다. (https://hides.tistory.com/1015) 현재 Reference 방식을 사용하여 도큐먼트를 모델링하던 중 ObjectId를 사용하지않고 원하는 필드를 사용하는 방법에 대해 궁금해졌고 그 방법에 대해 포스팅한다. 먼저 아래와 같이 User, Item 두개의 모델을 정의한다.
from mongoengine import *
connect('test')
class User(Document):
user_id = StringField()
user_pw = StringField()
class Item(Document):
user_id = ReferenceField(User, required=True)
description = StringField()
Item 모델의 user_id부분에 User를 걸어줬다. 여기에서 Referenced한 User를 담아주려면 다음과 같은 방법으로 진행해줘야 했다.
user = User.objects(user_id='hide').first()
item = Item.objects(description='item1').first()
print(item.user_id)
위와 같은 형태로 코드를 작성하고 실행시켜보면 User모델이 나오는것을 확인할 수 있다. 이는 Item 모델의 user_id가 ReferenceField이기 때문에 User모델 객체를 넘겨주면 자동으로 해당 객체의 ObjectId를 저장하기 때문이다. 그리고 해당 값을 통해 실제 User 도큐먼트에 일치하는 값을 찾아주는 형태이다. 보통의 경우에는 위와 같이 작업해도 큰 문제가 없지만 나는 현재 MySQL에 저장되어있던 값들을 MongoDB로 마이그레이션하는 과정 중 인데, ObjectId가 따로 존재하지 않기에 문제가 발생했다. 따라서 User 모델의 ObjectId가 아닌 user_id를 넣어주고 싶었다. 따라서 아래와 같은 코드를 작성해봤다.
User(user_id='hide', user_pw='123').save()
user = User.objects(user_id='hide').first()
Item(user_id=user.user_id, description='item1').save()
item = Item.objects(description='item1').first()
print(item.user_id)
처음 코드와 다른 점이 있다면, user객체를 가져와서 그대로 넣어주는것이 아닌 user_id값을 넣어줬다. 하지만 이대로 실행시켜보면 아래와 같은 오류가 발생한다.
mongoengine.errors.DoesNotExist: Trying to dereference unknown document DBRef('user', 'hide')
생각해보니 ReferenceField로 특정 모델을 넘겨주면 해당 모델에서 Primary한 키를 자동으로 찾아서 해당 필드를 통해 검색을 진행하는 형태일텐데 나는 기존 Primary key는 자동으로 생성되는 _id에 걸려있기 때문에 제대로 동작을 하지 않는것이 아닐까라는 생각이 들었다.
class User(Document):
user_id = StringField(primary_key=True)
user_pw = StringField()
class Item(Document):
user_id = ReferenceField(User, required=True)
description = StringField()
if __name__ == '__main__':
User(
user_id='hide',
user_pw='123'
).save()
user = User.objects(user_id='hide').first()
Item(
user_id=user.user_id,
description='item1'
).save()
user = User.objects(user_id='hide').first()
item = Item.objects(description='item1').first()
print(item.user_id.user_pw)
전과 달라진 점이 있다면 User모델의 user_id 부분에 primary_key=True 속성을 걸어준 것이다. 위처럼 작성하면 Item의 user_id는 ReferenceField이므로 저장된 값을 참조 대상 모델의 Primary key값을 통해 자동으로 연결시킨다.
'Coding > Python' 카테고리의 다른 글
Django Custom Command 만드는 방법 (0) | 2019.05.22 |
---|---|
Django QuerySet에 대하여 (0) | 2019.04.29 |
Python datetime으로 시간 더하고 빼는 방법 (0) | 2019.03.25 |
MongoEngine EmbeddedDocument/Reference (0) | 2019.03.18 |
Django AWS Elasticache 연동하는 방법 (0) | 2019.03.13 |