Django가 다른 Polymorphic과 거동이 다른 건
9949 단어 데이터베이스Python3Railspolymorphic장고
Polymorphism
프로그래밍에는 Polymorphism이라는 생각이 있으며 Wkipedia에는 다음과 같이 게재되어 있습니다. 링크
폴리모피즘(영어: Polymorphism)은 프로그래밍 언어의 형태 시스템의 성질을 나타내는 것으로, 프로그래밍 언어의 각 요소(정수, 변수, 식, 객체, 함수, 메소드 등)에 대해 그것들이 복수의 형태에 속하는 것을 용서한다는 성질을 가리킨다.
마찬가지로, 본래 RDB에서는 하나의 컬럼은 하나의 테이블에 대해서만 관계를 가지는 곳을, 복수의 테이블에 대해서 관계를 가지는 (복수의 형태에 속하는)와 같은 테이블을 Plymorphic Model이라고 합니다 .
SQL 안티패턴에서 소개된 폴리모픽 관련
SQL 안티 패턴 라는 책을 아십니까? RDB의 설계와 쿼리의 안티 패턴과 그 해결 방법을 소개 해설하고 있습니다.
그 중 폴리모픽 관련에 대해서도 해설이 있었으므로 샘플로서 소개합니다.
개요를 해설하면 Bugs(버그 기표) 테이블, FeatureRequests(기능 요망) 테이블이 있어, 각각에 Comments(코멘트)를 붙일 수 있다.
Comments의 issue_id는 Bugs의 bug_id, FeatureRequests의 requesst_id가 저장되고, 어느 테이블을 연결하고 있는지를 결정하기 위해 issue_type에 'Bugs'또는 'FeatureRequests'를 저장한다.
이때 실제로 발행되는 SQL이나 DB의 외래 키를 사용할 수 없는 것이, 버그등의 원인이 된다고 언급되고 있습니다.
장고 Polymorphic의 이상한 움직임
django-polymorphic과 Rails ActiveRecord를 비교하여 거동의 차이를 확인할 수 있습니다.
튜토리얼에 따라 각각을 구현하면 다음과 같습니다.
Rails
모델 파일
class Comment < ApplicationRecord
belongs_to :commentable, polymorphic: true
belongs_to :
end
class Bug < ApplicationRecord
has_many :comments, as: :commentable
end
class FeatureRequest < ApplicationRecord
has_many :comments, as: :commentable
end
migration 파일
class CreateComments < ActiveRecord::Migration[5.0]
def change
create_table :comments do |t|
t.string :comment
t.references :commentable, polymorphic: true
t.timestamps
end
end
end
Craete와 Read
# Create
Bug.create(title: "bug", description: "hello")
FeatureRequest.create(title: "feature request", description: "hello")
Comment.create(comment: 'comment on Bug', commentable_type: 'Bug', commentable_id: 1)
Comment.create(comment: 'comment on FeatureRequest', commentable_type: 'FeatureRequest', commentable_id: 1)
# Read
Bug.first.comments.first
#<Comment id: 1, comment: "comment on Bug", commentable_type: "Bug", commentable_id: 1, created_at: "2019-09-22 15:55:44", updated_at: "2019-09-22 15:55:44">
FeatureRequest.first.comments.first
#<Comment id: 1, comment: "comment on FeatureRequest", commentable_type: "FeatureRequest", commentable_id: 1, created_at: "2019-09-22 15:55:44", updated_at: "2019-09-22 15:55:44">
장고
from django.db import models
from polymorphic.models import PolymorphicModel
class Comment(PolymorphicModel):
id = models.BigAutoField(primary_key=True)
comment = models.TextField()
class Bug(Comment):
title = models.TextField()
description = models.TextField()
class FeatureRequest(Comment):
title = models.TextField()
description = models.TextField()
Create 및 Read
# Create
Bug(comment='Bug', title="Bug title", description="Bug description").save()
FeatureRequest(comment='FeatureRequest', title="FeatureRequest title", description="FeatureRequest description").save()
# Read
Comment.objects.first()
# <Bug: Bug object (1)>
해설
Rails는 SQL 안티 패턴 예제의 테이블을 생성했습니다.
SQL 안티 패턴에서도 다루어지는 것처럼, Comment와 Bug, Comment와 FeatureRequest는 각각 외부 결합하지 않지만 ActiveRecord에 의해 그것을 의식하지 않아도 된다.
반면 Django의 PolymorphicModel의 동작은 완전히 다릅니다.
생성된 DB를 ER에 일으키면 다음과 같이 됩니다.
Bugs, FeatureRequest는 모두 comment_ptr_id에서 Comments와 결합되어 있습니다.
이것은 Bugs, FeatureRequest가 공통 속성 Comments를 상속 (inherit)하는 것 같습니다.
더욱 일대일의 관계가 되어 있기 때문에, 원래 했던 것은 더 이상 할 수 없습니다.
감상
Django의 PolymorphicModel은 SQL 안티 패턴으로 다루어지는 소위 폴리 모픽 관련과 완전히 다르다는 것을 알았습니다.
더 이상 PolymorphicModel과 다형성 관련이 다른 것을 가리키는? 심지어 느끼는 수준입니다.
Reference
이 문제에 관하여(Django가 다른 Polymorphic과 거동이 다른 건), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/cohey0727/items/c5c0c03670ae191c6348텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)