【FastAPI 04】FastAPI如何优雅的连接数据库?

大家好,我是Kuls。

这是《小白学FastAPI》系列的第四篇文章。

在前面一篇文章中,我们有去写一个简单的博客框架,对它的路径、查询参数及路径参数函数等进行了学习。

今天我们来学习FastAPI的数据库连接,当然我们不仅仅只是为了学习这个知识点而学习。

今天K哥也来给大家说说如何去优雅的写一个FastAPI项目。

这是我今天所要讲解所编写项目的文件格式。

大家可以看到我们会在里面新建一个blog库来存放我们编写博客相关的操作,而不是像前面我们所写的,直接写一个main.py就行了。

那样对于我们编写一个项目是不太好的。

我们编写一个项目可以先创建一个虚拟环境,如果你还不懂虚拟环境是什么,可以去看下我的这篇文章 虚拟环境真的太重要了,很多人还不知道!

$ cd demo3-blog/
$ ls
__init__.py             blog                    requirements.txt

$ python -m venv blogenv
$ ls
__init__.py             blog                    blogenv                 requirements.txt

$ source blogenv/bin/activate

随后创建一个requeriment.txt,里面填写这个项目要使用的第三方库。

fastapi
uvicorn
sqlalchemy
pymysql

执行

pip install -r requeriment.txt

好了,上面其实算是题外话。

今天我们的主角其实是SQLAlchemy,可能之前学过Django或Flask的同学应该接触过SQLAlchemy。

我们看下官网的解释:SQLAlchemy is the Python SQL toolkit and Object Relational Mapper that gives application developers the full power and flexibility of SQL.

简答理解,它是一个sql工具箱,是一个ORM框架。

ORM:对象关系映射,你可以简单理解为 Python中的一个类映射一张数据表。

其实关于SQLAlchemy,里面有很多的知识,我也把它的详细的基础使用方法链接给大家。

官方文档:https://docs.sqlalchemy.org/en/14/orm/tutorial.html

本篇文章中我们也会学习SQLAlchemy。

database.py

还记得我们创建的database.py文件吗?我们将会在这里面编写数据库相关的内容:

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

SQLALCHEMY_DATABASE_URL = 'mysql+pymysql://user:password@localhost/fastapi'
engine = create_engine(SQLALCHEMY_DATABASE_URL)
SessionLocal = sessionmaker(bind=engine, autocommit=False, autoflush=False)
Base = declarative_base()

这里我们一行一行来进行分析

engine = create_engine(SQLALCHEMY_DATABASE_URL)'

这一行创建了我们的数据库引擎,我们就是通过这个引擎来创建表等各种操作的。其中的参数就是我们数据库的连接url,fastapi支持的数据库非常的多。

这里提醒一下,如果我们使用的是sqlite数据库,我们需要在create_engine的参数中新增connect_args={“check_same_thread”: False}

下面也是官网给出的支持的数据库,这些我们都可以通过sqlalchemy来进行连接。

  • PostgreSQL
  • MySQL
  • SQLite
  • Oracle
  • Microsoft SQL Server, etc.

关于具体数据库的url是啥,这里我给出官网,大家可以进行查阅

https://docs.sqlalchemy.org/en/14/core/engines.html

SessionLocal = sessionmaker(bind=engine, autocommit=False, autoflush=False)

这里我们创建的是SessionLocal,后续我们用到会进行讲解。

Base = declarative_base()

通过declarative_base()方法生成的类,该类是我们后面要用到的ORM 模型所要继承的父类。

models.py

既然数据库相关的配置都弄好了,接下来我们编写一个模型。

其实这个模型在我们上一篇文章中就已经编写过了。

但是还是有一些不同

from sqlalchemy import Column, Integer, String, Boolean
from .database import Base

class Blog(Base):
    __tablename__ = 'blog'

    id = Column(Integer, primary_key=True, index=True) # 设置主键和索引
    title = Column(String(32))
    content = Column(String(32))
    pulished = Column(Boolean)

大家可以发现,其实非常的直观和简单,无非就是创建一个类,里面有一些字段变量。

其中的__tablename__表示的是我们待会创建数据表的名称。

schemas.py

这个其实很简单,就是将我们在main.py中所编写的

from pydantic import BaseModel
from typing import Optional

class Blog(BaseModel):
    title: str
    content: str
    published: Optional[bool]

这部分内容搬到了一个新的文件当中,方便我们统一管理。

main.py

其实main.py跟我们上一篇文章的中的main.py差不多,只是多了几行代码:

from fastapi import FastAPI
from .database import engine
from . import schemas,models
from typing import Optional
app = FastAPI()

models.Base.metadata.create_all(engine)

# 博客首页
@app.get('/blog')
def index(limit: int = 10, published: bool = True, sort: Optional[str] = None):
    return {'data': f'我是博客首页,显示{limit}篇内容,并且发布状态为{published},排序顺序是根据{sort}字段'}

@app.get('/blog/unpublished')
def unpublished():
    return {'data': '这里是没有发布的博文列表'}

@app.get('/blog/{id}')
def showblog(id: int):
    return {'data': f'这是id为 {id} 的博文'}

@app.get('/blog/{id}/comments')
def comments(id: int):
    return {'data': f'这是id为{id}的博文评论内容'}

@app.post('/blog')
def new_blog(blog: schemas.Blog):
    return {'data': f'博文标题:{blog.title},博文内容:{blog.content},博文发表状态:{blog.published}'}

其中的create_all()方法就帮助我们创建了数据表

运行

到了这里基本就大功告成。

我们直接运行

查看数据库,发现我们的数据表已经成功创建。

总结

好了,今天主要讲了数据库相关的操作以及编写项目时的注意事项。

数据库具体的读写删操作,我们会在后面继续写,也会基于这个blog来写。

因为公众号改版,所以大家一定要记得星标公众号。

整个系列的代码我都放在了github中,大家可以访问下面链接:

https://github.com/hellokuls/fastapi/tree/master

FastAPI优雅地处理数据库连接异常通常涉及到良好的错误处理和资源管理。以下是一些建议: 1. **异常捕获**: 使用Python的try-except块来包裹涉及数据库操作的部分。当遇到`DatabaseError`、`ConnectionRefusedError`或其他相关异常时,可以捕获它们。 ```python from fastapi import FastAPI from sqlalchemy.orm import Session app = FastAPI() @app.exception_handler(OperationalError) async def db_exception_handler(request, exc): # 记录错误信息到日志 logger.error(f"Database error occurred: {exc}") return {"error": "An unexpected database issue occurred."}, 500 ``` 2. **连接池管理**: 如果你在应用中使用连接池,如SQLAlchemy的`asyncio.create_task`,确保关闭连接以防止资源泄漏。使用`async with`语句可以帮助管理资源释放。 ```python async def get_db_connection(): async with engine.connect() as connection: yield connection @app.get("/items/") async def read_items(db: Session = Depends(get_db_connection)): try: items = db.query(Item).all() return items except Exception as e: db.close() # 关闭连接以防泄露 raise ``` 3. **错误处理装饰器**: 可以创建一个通用的装饰器,用于所有需要数据库访问的视图函数,确保每个函数都有合适的异常处理机制。 ```python def db_access(func): async def wrapper(*args, **kwargs): try: return await func(*args, **kwargs) except Exception as e: await handle_database_error(e) return wrapper # 在需要的地方使用这个装饰器 @db_access async def your_function(db): ... ``` 通过以上方法,你可以确保在遇到数据库连接问题时,应用能提供有用的错误反馈,并保持资源的合理使用。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kuls就是我

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值