Python基础入门 Day59:SQLModel 中的关系映射(Relationship)

32次阅读
没有评论

共计 1601 个字符,预计需要花费 5 分钟才能阅读完成。

关系型数据库的核心之一就是“关系”。在 SQLModel 中,我们可以方便地定义实体之间的多种关系,比如一对多、多对一等。今天,我们将通过一个示例,学习如何在 SQLModel 中设置关系映射。

一、定义一对多关系的数据模型

我们以“用户(User)”和“文章(Post)”为例:一个用户可以有多篇文章,一篇文章只能属于一个用户。

from typing import List, Optional
from sqlmodel import Field, SQLModel, Relationship

class Post(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    title: str
    content: str
    user_id: Optional[int] = Field(default=None, foreign_key="user.id")

class User(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    name: str
    posts: List[Post] = Relationship(back_populates="user")

Post.user = Relationship(back_populates="posts")

说明:

  • Post 中的 user_id 是一个外键,指向 User.id
  • User 中的 posts 是文章的列表,表示一个用户可以拥有多篇文章
  • 双向关系通过 back_populates 建立

二、创建数据库表

from sqlmodel import create_engine

sqlite_url = "sqlite:///./blog.db"
engine = create_engine(sqlite_url, echo=True)
SQLModel.metadata.create_all(engine)

三、添加用户与文章记录

from sqlmodel import Session

def create_user_with_posts():
    with Session(engine) as session:
        user = User(name="Alice")
        post1 = Post(title=" 第一篇文章 ", content=" 内容一 ", user=user)
        post2 = Post(title=" 第二篇文章 ", content=" 内容二 ", user=user)
        session.add(user)
        session.add(post1)
        session.add(post2)
        session.commit()

四、查询用户及其文章

def get_user_and_posts(user_id: int):
    with Session(engine) as session:
        user = session.get(User, user_id)
        if user:
            print(f" 用户:{user.name}")
            for post in user.posts:
                print(f" 文章:{post.title} - {post.content}")

五、查询文章及所属用户

def get_post_and_user(post_id: int):
    with Session(engine) as session:
        post = session.get(Post, post_id)
        if post and post.user:
            print(f" 文章:{post.title},作者:{post.user.name}")

六、小结

通过 Relationship 配合 foreign_keyback_populates,SQLModel 能够优雅地建立表与表之间的关系。理解并掌握这些关系是构建实际项目数据库模型的关键。下一节我们将介绍更多进阶的查询操作,比如联表查询、条件过滤与分页处理。

正文完
 0
评论(没有评论)