Day 3 详细学习计划:数据库集成(SQLite + SQLModel)

学习目标

  • 学习 SQLModel 的基本用法
  • 理解 ORM(Object Relational Mapping) 的概念
  • 创建 SQLite 数据库并定义表结构
  • 实现数据的增删改查操作

1. SQLModel 简介

重要性:

  • 由 FastAPI 作者开发的库
  • 结合了 SQLAlchemy 和 Pydantic 的优点
  • 提供数据库模型和数据验证的统一接口
    有时间的话可以看下官方文档

安装命令:

pip install sqlmodel

这个很简单,一次成功

2. SQLite 简介-时间充裕可以看下官方文档

优势:

  • 轻量级文件型数据库
  • 无需单独的服务器进程
  • 零配置,无需额外安装
  • 适合小型项目和原型开发

3. ORM 概念-时间充裕可以看下官方文档

ORM (Object Relational Mapping):

  • 对象关系映射
  • 将数据库中的表映射为程序中的对象
  • 通过操作对象来操作数据库
    ORM 的作用是把数据库中的表映射为程序中的对象,然后通过操作对象来操作数据库。
    开始敲代码
    创建一个database.py文件 和一个main.py文件
    手写输入代码,不要复制

database.py

from sqlmodel import SQLModel, create_engine, Field, Session
from typing import Optional
from datetime import datetime

# 定义文章模型,既是数据库模型又是 Pydantic 模型
class......

main.py (更新版)

from fastapi import ......

上面代码我手敲一遍但是又很很多问题,所以我整理后正确的代码是这样的

# ==========database.py==========
from sqlmodel import SQLModel, create_engine, Field, Session
from typing import Optional
from datetime import datetime
from sqlmodel import Field
from typing import Optional

# 定义文章模型,既是数据库模型又是pydantic的数据模型
class Article(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    title: str
    content: str
    author: Optional[str] = None
    published: bool = False
    created_at: Optional[datetime] = Field(default_factory=datetime.utcnow, sa_type=None)

# 数据库文件Url
DATABASE_URL = "sqlite:///./articles.db"

# 创建数据库引擎
engine = create_engine(DATABASE_URL, echo=True)

# 创建表格
def create_db_and_tables():
    SQLModel.metadata.create_all(engine)

# 获取数据库会话
def get_session():
    with Session(engine) as session:
        yield session
# ==========main.py==========
from fastapi import FastAPI, Depends, HTTPException
from sqlmodel import Session, select
from typing import List
from contextlib import asynccontextmanager
from datetime import datetime
from database import engine, Article, create_db_and_tables, get_session

@asynccontextmanager
async def lifespan(app: FastAPI):
    # 应用启动时创建数据库表
    create_db_and_tables()
    yield
    # 应用关闭时可以执行清理工作

app = FastAPI(lifespan=lifespan)

# 创建文章
@app.post("/articles/", response_model=Article)
def create_article(article: Article, session: Session = Depends(get_session)):
    # 如果没有提供created_at,则使用当前时间
    if article.created_at is None:
        article.created_at = datetime.utcnow()
    session.add(article)
    session.commit()
    session.refresh(article)
    return article

# 获取所有文章
@app.get("/articles/", response_model=List[Article])
def read_articles(session: Session = Depends(get_session)):
    articles = session.exec(select(Article)).all()
    return articles

# 根据ID获取单个文章
@app.get("/articles/{article_id}", response_model=Article)
def read_article(article_id: int, session: Session = Depends(get_session)):
    article = session.get(Article, article_id)
    if not article:
        raise HTTPException(status_code=404, detail="Article not found")
    return article

# 更新文章
@app.put("/articles/{article_id}", response_model=Article)
def update_article(
    article_id: int, 
    article_update: Article, 
    session: Session = Depends(get_session)
):
    article = session.get(Article, article_id)
    if not article:
        raise HTTPException(status_code=404, detail="Article not found")
    
    # 更新文章字段
    article_data = article_update.dict(exclude_unset=True)
    for key, value in article_data.items():
        # 特殊处理created_at字段
        if key == "created_at" and isinstance(value, str):
            try:
                # 尝试解析ISO格式的日期字符串
                article_data[key] = datetime.fromisoformat(value.replace("Z", "+00:00"))
            except ValueError:
                # 如果解析失败,使用当前时间
                article_data[key] = datetime.utcnow()
        setattr(article, key, article_data[key])
    
    session.add(article)
    session.commit()
    session.refresh(article)
    return article

# 删除文章
@app.delete("/articles/{article_id}")
def delete_article(article_id: int, session: Session = Depends(get_session)):
    article = session.get(Article, article_id)
    if not article:
        raise HTTPException(status_code=404, detail="Article not found")
    
    session.delete(article)
    session.commit()
    return {"ok": True}

写好后在day3里面开始运行
uvicorn main:app --reload
就会出现网页,打开http://127.0.0.1:8000/docs 开始添加一个文章
点击post,修改内容,点击提交execute出现200就算对了。
然后可以点击get,查看所有文章。里面应该就会出现你添加的文章了
同样要测试下更新文章和删除文章

今天学习了一个多小时,感觉没有前两天轻松了,出现了许多错误的地方,很多不理解的地方,只是把代码写上去,然后跑通了,没有详细的去理解了为什么,只是大概知道,我创建了一个一些接口可以通过接口获取、增加、修改、删除数据库中的数据。

database.py 文件创建了一个db的文件,存放我们针对接口做的一些操作结果。文件里面会多出来一个articles.db文件。
main.py 文件里面创建了接口,并且定义了接口的返回结果。

测试的时候,我们先运行database.py文件,然后运行main.py文件,然后打开浏览器,输入http://127.0.0.1:8000/docs,可以看到我们的接口,然后就可以测试了。

又很晚了,今天白天时间少,感觉学习的很仓促,没有很懂其中的原理,非常烂。

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐