django의 ORM은 직관적이지만 조회할 때 날아가요.😰상스러운 말
본제에 앞서 나 개인의 의견
저는 Django의 ORM을 좋아합니다. 쉽게 실현할 수 있기 때문입니다!
왜냐하면 제가 자바를 만졌을 때(3년 전쯤) 사용한 건
my batis
인데 그것보다 기술량이 훨씬 적고 모델을 바탕으로 직감이 강하거든요.하지만 딩고의 ORM은 호불호가 분명하다는 인상을 준다.
그 중에서 정적 언어 →python 등의 절차를 겪은 엔지니어들은 그다지 좋아하지 않는다.
이 가능하다, ~할 수 있다,...🤨
직관적
예를 들어 문장과 평론을 예로 들자!
class Article(models.Model):
title = models.CharField(max_length=100)
body = models.TextField()
class Comment(models.Model):
article = models.ForeignKey(Article, on_delete=models.CASCADE, related_name='comments')
body = models.TextField()
문장과 평론의 관계는 1대 기타이다.이런 상황은 어떻습니까?
댓글을 다 얻고 싶어요.
all_comments = Comment.objects.all()
print(all_comments)
The 느낌 쉬워!!SQL 발매 확인 좀...
느낌은
SELECT
project_comment.id,
project_comment.article_id,
project_comment.body
FROM
project_comment;
// アプリ名がprojectだと過程します
// 実際はLIMITで件数が絞られていますが、割愛します
죠!다음 상황은 어때요?
모든 댓글에 관련된 기사를 얻고 싶어요.
all_comments = Comment.objects.all()
for comment in all_comments:
print(comment.article) # モデルでFK指定しているため、順参照できる
간단하여 겉과 속이 다른 직관적인 느낌을 준다!SQL 발매 확인 좀...
SELECT project_comment.id, project_comment.article_id, project_comment.body FROM project_comment; # 4件取得できたと過程する
SELECT project_article.id, project_article.title, project_article.body FROM project_article WHERE id = [id=1のコメントのarticle_id];
SELECT project_article.id, project_article.title, project_article.body FROM project_article WHERE id = [id=2のコメントのarticle_id];
SELECT project_article.id, project_article.title, project_article.body FROM project_article WHERE id = [id=3のコメントのarticle_id];
SELECT project_article.id, project_article.title, project_article.body FROM project_article WHERE id = [id=4のコメントのarticle_id];
어!?!?왜 이렇게 많아!?!?
귀에 낙지가 났어요.😠 N+1 질문
이것이 N+1 문제입니다.😨😨😨
슬픈 것은, 물어보는 횟수도 많지 않고, 많지도 않다는 것이다...
Join이가 만든 SQL이야...
SELECT
project_comment.id,
project_comment.article_id,
project_comment.body,
project_article.id,
project_article.title,
project_article.body
FROM
project_comment
INNER JOIN project_article
ON project_comment.article_id = project_article.id
이렇게 될 것 같아!전선을 잘 분해해라...
all_comments = Comment.objects.all() # クエリ1
for comment in all_comments:
print(comment.article) # クエリ2
(조회 2 순환 all comments)
values
,values_list
등도 발생한다.Django REST framework
면 패치에서 엄정하게 처리한 경우에도 마찬가지로 보이지 않는 곳에서 조회가 발행된다.나는 이것
N+1問題
이 모르면 나도 모르게 빠져드는 함정이라고 생각한다.전가의 보도🥷 select_related , prefech_related
이것은 명확한 선포
inner join
,outer join
이다.매번 검색어가 발행될 때마다 DB에 연결되기 때문에, 먼저 Join을 명확하게 설명한 다음, 한 번의 검색어로 가져옵니다.
all_comments = Comment.objects.select_related('article').all()
for comment in all_comments:
print(comment.article) # クエリ飛ばない
반참조의 경우는 다음과 같다.어떤 기사(id=5)와 관련된 모든 평론을 얻고 싶습니다.
article = Article.objects.prefetch_related('comments').get(id=5)
comments = article.comments.all()
for comment in comments:
print(comment.body) # 先に取得しているのでクエリは発行されない
참고로 사용Prefetch
도 조회를 어떻게 얻는지 제어할 수 있습니다.article = Article.objects.prefetch_related(Prefetch(queryset=*クエリ文)).all()
최후
이렇게 Django의 ORM을 사용하려면 모델의 관계와 데이터가 어떻게 처리되는지 알아야 한다.
데이터가 어떻게 사용되는지 깨닫고 코드를 쓰는 것은 좀 번거롭기 때문에 일반적으로 엄숙한 대상이나 데이터클래스 등으로 설계된다.
인식된 레이어
my batis
와 SQL이 많이 다르지 않음😅모델을 직관적으로 접촉하는 것은 무엇이든 할 수 있는 것이고 위험하다.
이 위험한 부분을 잘 이해하는 것은 Django의 ORM을 처리할 때 매우 중요하다고 생각합니다. 좋은 점도 알고 나쁜 것도 알고 정확하게 사용할 수 있는 엔지니어가 되는 것이 매우 중요합니다!
처음 공부하는 엔지니어에게 함정이다. 이 글을 통해 가문의 보검을 머릿속 어딘가에 남기고 싶다!!!
Reference
이 문제에 관하여(django의 ORM은 직관적이지만 조회할 때 날아가요.😰상스러운 말), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/ryohama/articles/51a27e5b644888텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)