9.3 数据库模型定义与关系
FastAPI 数据库模型定义与关系:Python 初学者完整实践指南
为Python初学者打造的FastAPI数据库模型定义与关系教程,通过生活化类比和简单示例,手把手教你快速掌握Web开发基础,建立实践信心。
FastAPI 入门教程:数据库模型定义与关系
引言:为什么需要数据库模型?
想象一下,你管理一个小图书馆:每本书都有书名、作者、出版日期等信息。在数字世界里,我们需要一种方式来存储和组织这些数据。数据库模型就像设计一个电子表格模板,定义数据如何存放;而关系则像在表格之间画线,连接相关信息(比如一本书属于一个作者)。
这个教程将用简单步骤带你构建一个FastAPI应用,通过数据库模型和关系管理数据,让你在几分钟内看到成果!
第一部分:准备工作——安装和设置
首先,确保你安装了Python。然后,打开终端或命令行,运行以下命令安装所需库:
pip install fastapi uvicorn sqlalchemy
这些库的作用:
- FastAPI:构建Web API框架。
- Uvicorn:运行FastAPI应用的服务。
- SQLAlchemy:一个ORM(对象关系映射)工具,让Python代码直接操作数据库,无需写复杂SQL。
现在,创建一个新文件夹,比如fastapi_db_tutorial,在里边新建一个文件main.py。
第二部分:定义第一个数据库模型——从简单开始
让我们从单种数据开始:定义一个Book模型,就像图书馆里的书一样。
在main.py中,添加以下代码:
from fastapi import FastAPI, HTTPException
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
# 创建一个FastAPI应用实例
app = FastAPI()
# 设置一个SQLite数据库(最简单,无需额外安装)
DATABASE_URL = "sqlite:///./test.db" # 这会创建一个test.db文件在你的文件夹里
engine = create_engine(DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base() # 这是定义模型的基础类
# 定义Book模型
class Book(Base):
__tablename__ = "books" # 数据库表名
id = Column(Integer, primary_key=True, index=True) # 主键,就像书的唯一编号
title = Column(String, index=True) # 书名,可以快速查找
author = Column(String) # 作者
year = Column(Integer) # 出版年份
# 创建所有表(如果不存在)
Base.metadata.create_all(bind=engine)
成功时刻: 运行应用,看看发生了什么!
在终端中,运行:
uvicorn main:app --reload
然后打开浏览器,访问http://127.0.0.1:8000/docs。你会看到FastAPI的交互式文档,这表明你的应用正在运行!虽然还没有端点,但模型已定义好,数据库文件test.db会出现在文件夹中。
第三部分:添加关系——连接作者和书
现在,扩展模型:添加一个Author模型,并建立关系。这就像在一个图书馆中,每本书都有一个作者,一个作者可以写多本书。
修改main.py,添加Author模型和关系:
from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship
# 继续之前的导入和设置...
# 定义Author模型
class Author(Base):
__tablename__ = "authors"
id = Column(Integer, primary_key=True, index=True)
name = Column(String, index=True)
birth_year = Column(Integer)
# 修改Book模型,添加关系
class Book(Base):
__tablename__ = "books"
id = Column(Integer, primary_key=True, index=True)
title = Column(String, index=True)
year = Column(Integer)
# 添加外键,指向Author的id
author_id = Column(Integer, ForeignKey("authors.id"))
# 建立关系:一本书属于一个作者,一个作者有多本书
author = relationship("Author", back_populates="books")
# 修改Author模型,添加反向关系
Author.books = relationship("Book", back_populates="author")
# 重新创建表以应用更改
Base.metadata.create_all(bind=engine)
类比: 这就像在电子表格中,Book表有一列author_id,它引用Author表的id列,建立了连接。
第四部分:实践——创建API端点操作数据
现在,添加一些FastAPI端点来操作数据。我们将实现基本的CRUD(创建、读取、更新、删除)操作。
在main.py中添加以下代码:
from pydantic import BaseModel
from typing import List
# Pydantic模型用于请求和响应数据
class AuthorCreate(BaseModel):
name: str
birth_year: int
class BookCreate(BaseModel):
title: str
year: int
author_id: int
class AuthorResponse(BaseModel):
id: int
name: str
birth_year: int
books: List["BookResponse"] = []
class BookResponse(BaseModel):
id: int
title: str
year: int
author_id: int
author: AuthorResponse = None # 由于关系,可以包含作者信息
# 更新AuthorResponse以包括BookResponse
AuthorResponse.update_forward_refs()
# API端点
@app.get("/")
def read_root():
return {"message": "欢迎使用FastAPI数据库教程!访问/docs查看API文档。"}
@app.post("/authors/", response_model=AuthorResponse)
def create_author(author: AuthorCreate):
db = SessionLocal()
db_author = Author(**author.dict()) # 创建Author实例
db.add(db_author)
db.commit()
db.refresh(db_author)
db.close()
return db_author
@app.get("/authors/{author_id}", response_model=AuthorResponse)
def read_author(author_id: int):
db = SessionLocal()
author = db.query(Author).filter(Author.id == author_id).first()
db.close()
if author is None:
raise HTTPException(status_code=404, detail="Author not found")
return author
@app.post("/books/", response_model=BookResponse)
def create_book(book: BookCreate):
db = SessionLocal()
db_book = Book(**book.dict())
db.add(db_book)
db.commit()
db.refresh(db_book)
db.close()
return db_book
@app.get("/books/{book_id}", response_model=BookResponse)
def read_book(book_id: int):
db = SessionLocal()
book = db.query(Book).filter(Book.id == book_id).first()
db.close()
if book is None:
raise HTTPException(status_code=404, detail="Book not found")
return book
成功时刻: 再次运行应用,并使用交互式文档测试API!
- 运行
uvicorn main:app --reload。 - 在浏览器中,访问
http://127.0.0.1:8000/docs。 - 首先,使用POST
/authors/创建一个作者(例如,输入{"name": "J.K. Rowling", "birth_year": 1965})。点击“Try it out”和“Execute”,你会看到返回数据。 - 然后,使用GET
/authors/1获取作者信息,应该能看到刚才创建的作者。 - 同样,用POST
/books/创建一本书(确保author_id对应已有作者),并测试GET端点。
第五部分:扩展和挑战——更进一步
现在,你已经学会了如何定义模型和基本关系。试试自己添加更多功能:
- 一对多关系:一个作者有多本书,我们已经实现。
- 一对一关系:例如,一个用户有一个个人资料表。
- 多对多关系:想象一本书可以有多个分类标签。这需要额外表,比如
BookTag关联表。
简单示例:添加一个Tag模型,并与Book建立多对多关系。你可以参考SQLAlchemy文档,但在实践中,建议先从当前模型开始。
总结
恭喜你!你已经构建了一个简单的FastAPI应用,用SQLAlchemy定义了数据库模型和关系。关键点:
- 模型:用Python类表示数据库表。
- 关系:使用外键和relationship连接模型。
- 实践:通过API端点操作数据,获得即时反馈。
保持实践:修改代码,添加更多字段或端点,享受编程的乐趣!遇到问题时,参考FastAPI和SQLAlchemy文档。祝你编程愉快!