SQLAlchemy - 자기 참조 관계를 1 대 다로 매핑하기 (선언적 형식)
개요
SQLAlchemy는 Python에서 데이터베이스와 상호 작용을 위한 강력한 객체 관계 매퍼(ORM)입니다. 자기 참조 관계는 한 테이블의 엔티티가 다른 같은 테이블의 엔티티를 참조하는 관계입니다. 예를 들어, 게시물 테이블에는 자체에 대한 참조를 포함하는 댓글 엔티티가 있을 수 있습니다.
이 문서에서는 SQLAlchemy를 사용하여 자기 참조 관계를 1 대 다 형식으로 매핑하는 방법을 보여줍니다.
예제
다음 예제에서는 게시물 및 댓글 엔티티를 정의하는 방법을 보여줍니다.
from sqlalchemy import create_engine
from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship
engine = create_engine("sqlite:///example.db")
Base = declarative_base()
class Post(Base):
__tablename__ = "posts"
id = Column(Integer, primary_key=True)
title = Column(String(255))
body = Column(String)
class Comment(Base):
__tablename__ = "comments"
id = Column(Integer, primary_key=True)
content = Column(String)
post_id = Column(Integer, ForeignKey("posts.id"))
post = relationship("Post", backref="comments")
Base.metadata.create_all(engine)
설명
Post
테이블에는id
,title
및body
열이 있습니다.Comment
테이블에는id
,content
및post_id
열이 있습니다.post_id
열은Post
테이블의id
열을 참조합니다.post
관계는Comment
엔티티가 참조하는Post
엔티티를 가져오는 데 사용됩니다.backref
매개변수는Post
엔티티에comments
관계를 만듭니다. 이 관계는Post
엔티티에 연결된 모든Comment
엔티티의 목록을 가져오는 데 사용됩니다.
사용 방법
다음 코드는 새 게시물 및 댓글을 만들고 관계를 설정하는 방법을 보여줍니다.
post = Post(title="My First Post", body="This is my first post.")
comment = Comment(content="This is my first comment.", post=post)
session.add(post)
session.add(comment)
session.commit()
결론
이 문서에서는 SQLAlchemy를 사용하여 자기 참조 관계를 1 대 다 형식으로 매핑하는 방법을 보여주었습니다. 자세한 내용은 SQLAlchemy 문서를 참조하십시오.
참고
추가 정보
- SQLAlchemy를 사용하여 다양한 관계 유형을 매핑하는 방법에 대한 자세한 내용은 SQLAlchemy 문서를 참조하십시오.
- 자기 참조 관계를 구현하는 다른 방법도 있습니다. 자세한 내용은 SQLAlchemy 문서를 참조하십시오.
예제 코드: SQLAlchemy를 사용하여 자기 참조 관계를 1 대 다 형식으로 매핑하기
다음은 python
및 sqlalchemy
를 사용하여 자기 참조 관계를 1 대 다 형식으로 매핑하는 방법을 보여주는 예제 코드입니다.
from sqlalchemy import create_engine
from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship
# 데이터베이스 엔진 생성
engine = create_engine("sqlite:///example.db")
# 기본 클래스 정의
Base = declarative_base()
# 게시물 테이블 정의
class Post(Base):
__tablename__ = "posts"
id = Column(Integer, primary_key=True)
title = Column(String(255))
body = Column(String)
# 댓글 테이블 정의
class Comment(Base):
__tablename__ = "comments"
id = Column(Integer, primary_key=True)
content = Column(String)
post_id = Column(Integer, ForeignKey("posts.id"))
# 댓글과 게시물 간의 관계 정의
post = relationship("Post", backref="comments")
# 테이블 생성
Base.metadata.create_all(engine)
# 새 게시물 및 댓글 만들기
post = Post(title="제목", body="본문")
comment1 = Comment(content="첫 번째 댓글", post=post)
comment2 = Comment(content="두 번째 댓글", post=post)
# 세션 생성 및 엔티티 추가
session = create_session()
session.add(post)
session.add(comment1)
session.add(comment2)
# 변경 내용 커밋
session.commit()
# 게시물 및 연결된 댓글 가져오기
post = session.query(Post).filter(Post.id == 1).one()
print(f"게시물 제목: {post.title}")
print(f"게시물 본문: {post.body}")
for comment in post.comments:
print(f"댓글 내용: {comment.content}")
# 세션 종료
session.close()
설명:
- 데이터베이스 엔진 생성:
create_engine()
함수를 사용하여 SQLite 데이터베이스 엔진을 생성합니다. - 기본 클래스 정의:
declarative_base()
함수를 사용하여 SQLAlchemy의 기본 클래스를 정의합니다. - 게시물 테이블 정의:
Post
클래스를 사용하여posts
테이블을 정의합니다. 해당 테이블에는id
,title
및body
열이 있습니다. - 댓글 테이블 정의:
Comment
클래스를 사용하여comments
테이블을 정의합니다. 해당 테이블에는id
,content
및post_id
열이 있습니다.post_id
열은posts
테이블의id
열을 참조합니다. - 관계 정의:
relationship()
데코레이터를 사용하여Comment
엔티티가 참조하는Post
엔티티를 가져오는post
관계를 정의합니다.backref
매개변수는Post
엔티티에comments
관계를 만듭니다. - 테이블 생성:
Base.metadata.create_all(engine)
를 사용하여 정의된 테이블을 데이터베이스에 생성합니다. - 새 게시물 및 댓글 만들기:
Post
및Comment
클래스의 인스턴스를 생성하여 새 게시물 및 댓글을 만듭니다. 댓글은post
속성을 사용하여 해당 게시물에 연결됩니다. - 세션 생성 및 엔티티 추가:
create_session()
함수를 사용하여 세션을 생성하고 새 엔티티를 추가합니다. - 변경 내용 커밋:
session.commit()
를 사용하여 데이터베이스에 변경 내용을 커밋합니다. - 게시물 및 연결된 댓글 가져오기:
session.query(Post).filter(Post.id == 1).one()
를 사용하여 ID가 1인 게시물을 가져옵니다. 그런 다음post.comments
반복자를 사용하여 해당 게시물에 연결된 모든 댓글을 출력합니다. - 세션 종료:
session.close()
를 사용하여 세션을 종료합니다.
SQLAlchemy를 사용하여 자기 참조 관계를 1 대 다 형식으로 매핑하는 대체 방법
앞서 설명한 방법 외에도 SQLAlchemy를 사용하여 자기 참조 관계를 1 대 다 형식으로 매핑하는 몇 가지 대체 방법이 있습니다.
다중 레벨 매핑
다중 레벨 매핑은 relationship()
데코레이터를 여러 번 사용하여 관계를 정의하는 방법입니다. 이 방법은 더 복잡하지만 더 유연한 옵션을 제공할 수 있습니다.
from sqlalchemy import create_engine
from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship
engine = create_engine("sqlite:///example.db")
Base = declarative_base()
class Post(Base):
__tablename__ = "posts"
id = Column(Integer, primary_key=True)
title = Column(String(255))
body = Column(String)
class Comment(Base):
__tablename__ = "comments"
id = Column(Integer, primary_key=True)
content = Column(String)
parent_id = Column(Integer, ForeignKey("comments.id"))
parent = relationship("Comment", back_populates="children")
post = relationship("Post", backref="comments")
children = relationship("Comment", back_populates="parent")
Base.metadata.create_all(engine)
# ... (나머지 코드는 동일함)
Comment
테이블에는parent_id
열이 추가됩니다. 이 열은 다른Comment
엔티티의id
열을 참조합니다.parent
관계는Comment
엔티티가 참조하는 부모Comment
엔티티를 가져오는 데 사용됩니다.back_populates
매개변수는 부모Comment
엔티티에children
관계를 만듭니다.children
관계는Comment
엔티티의 모든 자식Comment
엔티티의 목록을 가져오는 데 사용됩니다.
매핑 테이블 사용
매핑 테이블은 별도의 테이블을 사용하여 두 엔티티 간의 관계를 정의하는 방법입니다. 이 방법은 더 복잡하지만 더 명확하고 유지 관리하기 쉬울 수 있습니다.
from sqlalchemy import create_engine
from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy import Table
from sqlalchemy.orm import relationship
engine = create_engine("sqlite:///example.db")
Base = declarative_base()
post_table = Table(
"posts",
Base.metadata,
Column("id", Integer, primary_key=True),
Column("title", String(255)),
Column("body", String),
)
comment_table = Table(
"comments",
Base.metadata,
Column("id", Integer, primary_key=True),
Column("content", String),
Column("post_id", Integer, ForeignKey("posts.id")),
Column("parent_id", Integer, ForeignKey("comments.id")),
)
post_comment_table = Table(
"post_comment",
Base.metadata,
Column("post_id", Integer, ForeignKey("posts.id")),
Column("comment_id", Integer, ForeignKey("comments.id")),
)
class Post(Base):
__table__ = post_table
comments = relationship(
"Comment",
secondary=post_comment_table,
backref="posts",
lazy="dynamic",
)
class Comment(Base):
__table__ = comment_table
parent = relationship("Comment", back_populates="children")
children = relationship("Comment", back_populates="parent")
post = relationship("Post", backref="comments")
Base.metadata.create_all(engine)
# ... (나머지 코드는 동일함)
post_comment
테이블은post_id
및comment_id
열을 포함합니다. 이 열은 각각posts
및comments
테이블의id
열을 참조합니다.Post
및Comment
클래스는secondary
매개변수를 사용하여post_comment
테이블을 참조하는comments
관계를 정의합니다.lazy="dynamic"
매개
python sqlalchemy