IT科技类资讯

FastAPI 实战秘籍:从零构建高性能 API -数据库篇

字号+作者:益华科技来源:数据库2025-11-05 10:05:13我要评论(0)

前面我们讲了Fastapi日志、配置管理,在web开发中主要是针对数据库的增删改查,今天主要讲一下通过sqlalchemy连接数据库,数据库会话,数据库模型的创建和自动建表等。《FastAPI实战秘籍

前面我们讲了Fastapi日志、实I数配置管理,战秘在web开发中主要是籍从建高据库针对数据库的增删改查,今天主要讲一下通过sqlalchemy连接数据库,零构数据库会话,实I数数据库模型的战秘创建和自动建表等。

《FastAPI实战秘籍:从零构建高性能API-日志篇》《FastAPI实战秘籍:从零构建高性能API-配置篇》

准备工作

对象关系映射操作库:

复制pip install sqlalchemy1.

数据库连接配置,籍从建高据库在config.yaml中增加如下如下配置:

复制# config.yaml database: url: "mysql+pymysql://root:123456@127.0.0.1:3306/zadmin" async_url: "mysql+asyncmy://root:123456@127.0.0.1:3306/zadmin" pool_size: 20 echo_sql: false # 是零构否打印SQL日志1.2.3.4.5.6.

需要安装pymysql和asyncmy库,处理同步及异步请求:

复制pip install pymysql asyncmy1.

在前面讲解配置中我们设置了配置加载及定义:

复制# config.py class DatabaseConfig(BaseModel): url: str async_url: str pool_size: int = 10 echo_sql: bool = False class Settings(BaseSettings): ... database: DatabaseConfig ...1.2.3.4.5.6.7.8.9.10.11.12. 数据库连接

在core下创建database.py文件。实I数使用sqlalchemy连接数据库,战秘数据源的籍从建高据库定义如下:

复制database_url dialect+driver://username:password@host:port/database # 数据库连接配置 # MySQL示例: mysql+pymysql://username:password@localhost/dbname # PostgreSQL示例: postgresql+psycopg2://username:password@localhost/dbname1.2.3.4.5.

(1) 创建数据库引擎(Engine)

复制# core/database.py from sqlalchemy import create_engine from sqlalchemy.ext.asyncio import create_async_engine from config.config import get_settings settings = get_settings() # 异步引擎 async_engine = create_async_engine( url = settings.database.async_url, echo=settings.database.echo_sql, pool_size=settings.database.pool_size ) # 同步引擎 engine = create_engine( url = settings.database.url, echo=settings.database.echo_sql, pool_size=settings.database.pool_size )1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.

(2) 创建会话工厂(Session Factory)

「会话工厂」是一个用于创建会话实例的工厂函数或类。b2b信息网它预先配置了会话的零构各种参数,但不会立即创建数据库连接。实I数

复制# core/database.py # 同步会话工厂 session_local = sessionmaker( autocommit=False,战秘 autoflush=False, bind=engine) # 异步会话工厂 session_factory = async_sessionmaker( autocommit=False, autoflush=False, bind=async_engine, expire_on_commit=True, class_=AsyncSession )1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.

(3) 创建会话(Session)

「会话」是SQLAlchemy ORM的核心,它代表了一个与数据库的籍从建高据库"对话",负责:

管理对象状态执行数据库操作处理事务维护对象标识映射 复制# 异步会话 async def get_async_db(): async with session_factory() as session: async with session.begin(): yield session # 同步会话 def get_db(): with session_local() as session: yield session1.2.3.4.5.6.7.8.9.10.

不使用上下文管理器,也可以通过下面方式定义

复制def get_db(): db = session_local() try: yield db finally: db.close()1.2.3.4.5.6. 基类定义及自动建表 复制# 定义基类,所有其它数据实体都继承于它 Base = declarative_base() # 如下示例:用户表模型,除了__*__属性,其它通过mapper或Column定义的都对应表的字段 # class User(Base): # __tablename__ = users # __table_args__ = ({comment: 用户表}) # id: Mapped[int] = mapped_column(Integer, primary_key=True, comment=主键ID) # telephone: Mapped[str] = mapped_column(String(11), unique=True,comment="手机号码")1.2.3.4.5.6.7.8.9.

自动建表:

复制def create_all_tables(): Base.metadata.create_all(bind=engine) # 由于main.py中的函数代码都是同步的,b2b供应网所以下面的函数基本上用到。 async def async_create_all_tables(): async with async_engine.begin() as conn: # 使用 run_sync 在异步上下文中执行同步操作 await conn.run_sync(Base.metadata.create_all)1.2.3.4.5.6.7.8.

在main.py中使用:

复制from core import register_exception, database def create_app(): """启动项目""" ... database.create_all_tables()1.2.3.4.5.6. 高级应用

由于我们创建的数据表大部分u都有created_at、id、updated_at字段,我们可以自定义基类:

复制# 定义一个公共模型 class BaseModel(Base): """ 公共 ORM 模型,基表 """ __abstract__ = True id: Mapped[int] = mapped_column(Integer, primary_key=True, comment=主键ID) created_at: Mapped[datetime] = mapped_column( DateTime, default=func.now(), comment=创建时间) updated_at: Mapped[datetime] = mapped_column( DateTime, default=func.now(), onupdate=func.now(), comment=更新时间 ) deleted_at: Mapped[datetime] = mapped_column( DateTime, nullable=True, comment=删除时间)1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.

这样上面的User模型就可以简化为下面的方式,去掉了ID主键的定义:

复制# class User(BaseModel): # __tablename__ = users # __table_args__ = ({comment: 用户表}) # telephone: Mapped[str] = mapped_column(String(11), unique=True,comment="手机号码")1.2.3.4. 演示

在models下创建文件user.py,定义模型内容如下:

复制# models/user.py from sqlalchemy import String from sqlalchemy.orm import Mapped, mapped_column from core.database import BaseModel, TableName from passlib.context import CryptContext pwd_context = CryptContext(schemes=[bcrypt], deprecated=auto) @TableName("users") class User(BaseModel): telephone: Mapped[str] = mapped_column(String(11), index=True, unique=True, comment="手机号码") password: Mapped[str] = mapped_column(String(128), comment="密码") username: Mapped[str] = mapped_column(String(50), index=True, nullable=False, comment="姓名") @staticmethod def get_password_hash(password: str) -> str: """ 生成哈希密码 :param password: 原始密码 :return: 哈希密码 """ return pwd_context.hash(password) @staticmethod def verify_password(password: str, hashed_password: str) -> bool: """ 验证原始密码是否与哈希密码一致 :param password: 原始密码 :param hashed_password: 哈希密码 :return: """ return pwd_context.verify(password, hashed_password)1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.33.

(1) 定义路由,实现增删改查操作

打开数据库连接工具比如navicat,然后创建数据库zadmin 启动服务。

(2) 异步操作

复制@app.get("/curd/async") asyncdef async_curd( db: AsyncSession = Depends(get_async_db), ): """创建用户""" hashed_password = User.get_password_hash("123456") user = User(telephone="13800000090", password=hashed_password, username="admin") db.add(user) await db.commit() await db.refresh(user) print("add user {} {} {}".format(user.username, user.telephone, user.id)) """根据ID获取用户""" result = await db.execute(select(User).where(User.id == 3)) user = result.scalar() print(" scalar_one_or_none user {} {} {}".format(user.username, user.telephone, user.id)) """获取所有用户(分页)""" result = await db.execute(select(User).offset(0).limit(10)) print(result.scalars().all()) """更新用户信息""" stmt = update(User).where(User.id == 1).values({"telephone":"13522023423"}) result = await db.execute(stmt) print(result) result = await db.execute(select(User).where(User.telephone == "13522023423")) user = result.scalar_one_or_none() print(user) # 删除操作 stmt = delete(User).where(User.id == 3) result = await db.execute(stmt) await db.commit()1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.33.34.

同步操作:

复制@app.get("/curd/sync") asyncdef sync_curd( db: Session = Depends(get_db), ): """同步创建用户""" hashed_password = User.get_password_hash("123456") user = User(telephone="13800000090", password=hashed_password, username="admin") db.add(user) db.commit() db.refresh(user) print("add user {} {} {}".format(user.username, user.telephone, user.id)) """单行查询""" user = db.query(User).filter(User.id == 3).first() print("user by id {} {} {}".format(user.username, user.telephone, user.id)) """更新操作""" user = db.query(User).filter(User.id == 3).first() user.telephone = "13522023423" db.query(User).filter(User.id == 3).update({"telephone":"13522023423"}) db.commit() db.refresh(user) user = db.query(User).filter(User.id == 1).first() db.delete(user) db.commit()1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.源码下载

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • 电视果投屏器的使用体验和性能评测(探索一款智能家居设备的魅力与局限性)

    电视果投屏器的使用体验和性能评测(探索一款智能家居设备的魅力与局限性)

    2025-11-05 09:43

  • 域名解析要知道哪些?新手要如何完成动态域名解析?

    域名解析要知道哪些?新手要如何完成动态域名解析?

    2025-11-05 08:26

  • ren域名什么域名?ren域名有哪些特点?

    ren域名什么域名?ren域名有哪些特点?

    2025-11-05 07:56

  • 为何投资者都冲高PR域名去?高PR域名有什么特殊意义?

    为何投资者都冲高PR域名去?高PR域名有什么特殊意义?

    2025-11-05 07:55

网友点评
精彩导读
我在过去已经多次涉及到在UEFI模式下安装Ubuntu 14.04与Windows 8/8.1双启动的话题。 但是要怎么从Windows双启动中卸载Ubuntu呢?下面我们将看到的教程适用于任意的Linux操作系统,如Ubuntu,Linux Mint,Elementary OS或其它任意Linux发行版。假如你认为在双启动模式下安装Ubuntu与Windows 8共存是件难事,而从Windows双启动中移除Ubuntu将是很简单的,你的想法并不是完全错误的。假如你有个Windows安装介质的话,从Windows双启动中卸载Linux将是轻而易举的。这个教程将教你如何在有Windows 8/8.1安装介质的情况下将Linux从Windows 8或Windows 8.1双启动中完全移除。将Ubuntu从Windows 8双启动中安全卸载你有没有Windows 8安装介质以及是否已经安装了Windows 8.1在你系统上这都不重要。它同样工作得很好。但是我不能说在Windows 7上也一样。假如你身边有Windows安装盘,让我们开始从Windows双启动中移除Ubuntu的进程吧。从双启动中删除Linux分为两部分。第一部分是删除Linux安装的所在分区。第二部分是修复Windows启动引导,因为简单地将Linux分区删除会引起“Grub rescue”错误。第一部分:在Windows下删除Linux分区第一步:登录Windows。按下 Windows+R 然后在其中运行 diskmgmt.msc 命令。它将会打开Windows磁盘管理工具。第二步:在你安装了Linux之后,就能很容易地从大小上分辨出Linux分区。另一个分辨Linux分区的提示是找没有文件系统以及驱动器卷标的分区。Windows分区通常用卷标进行标记,比如C,D,E等等,而且通常是NTFS或FAT文件系统。就像你所能看到的,我在这里有三个Linux分区,因为我在安装Ubuntu时单独地创建了根分区(root),交换分区(swap)和家目录(home)。Step 3: 第三步:选择Linux分区,右键点击并选择 删除卷 选项。假如出现了警告,在这里选择是即可。Step 4: 第四步:被删除的分区会变成一块可用的空闲空间。你可以用它来扩展已有的卷或创建一个新的Windows分区。我会建议你创建一个新的驱动器(或是卷或者分区,随便你怎么叫),因为这样子万一你将来又想将Linux和Winodws双启动时会简单一点。第二部分:修复Windows启动引导一旦你删除了Linux分区,就是时候修复Windows启动引导了。这里的图片看起来可能不是很清楚,因为相对于Windows来说在Ubuntu下对登录画面进行截图要简单的多。我用手机相机拍下了这些照片。第一步:插入Windows 8安装介质并重启你的电脑。在启动的时候按下F10或F12进入BIOS/UEFI,选择从可移除介质启动(boot from removable disk)。第二步:选择修复你的计算机(repair your computer):第三步:在这里选择疑难解答(Troubleshoot):第四步:在疑难解答页面,选择高级选项(Advanced options):第五步:找到这里的命令提示符(command prompt):第六步:在命令行中输入下列命令来修复Windows启动引导:bootrec.exe /fixmbr正常情况下,它是立即生效的,你甚至都不用等。第七步:一旦完成了这一步,重启你的电脑,这次从硬盘正常启动。你应该能够启动进入Windows。假如你仍然看到Grub rescue错误,试试下面的步骤。第八步:假如第六步中的方法不起作用假如第六步中的命令不起作用,试试高级疑难解答中的自动修复选项。它会花点时间查找问题然后修复它。现在假如你重启的话,你应该能够正常进入Windows,不再看到任何的Grub rescue错误提示。我希望这个指南能够帮助你将Ubuntu从Windows 8双启动中完全移除。欢迎提出任何问题与建议。谢谢阅读,希望能帮到大家,请继续关注脚本之家,我们会努力分享更多优秀的文章。

我在过去已经多次涉及到在UEFI模式下安装Ubuntu 14.04与Windows 8/8.1双启动的话题。 但是要怎么从Windows双启动中卸载Ubuntu呢?下面我们将看到的教程适用于任意的Linux操作系统,如Ubuntu,Linux Mint,Elementary OS或其它任意Linux发行版。假如你认为在双启动模式下安装Ubuntu与Windows 8共存是件难事,而从Windows双启动中移除Ubuntu将是很简单的,你的想法并不是完全错误的。假如你有个Windows安装介质的话,从Windows双启动中卸载Linux将是轻而易举的。这个教程将教你如何在有Windows 8/8.1安装介质的情况下将Linux从Windows 8或Windows 8.1双启动中完全移除。将Ubuntu从Windows 8双启动中安全卸载你有没有Windows 8安装介质以及是否已经安装了Windows 8.1在你系统上这都不重要。它同样工作得很好。但是我不能说在Windows 7上也一样。假如你身边有Windows安装盘,让我们开始从Windows双启动中移除Ubuntu的进程吧。从双启动中删除Linux分为两部分。第一部分是删除Linux安装的所在分区。第二部分是修复Windows启动引导,因为简单地将Linux分区删除会引起“Grub rescue”错误。第一部分:在Windows下删除Linux分区第一步:登录Windows。按下 Windows+R 然后在其中运行 diskmgmt.msc 命令。它将会打开Windows磁盘管理工具。第二步:在你安装了Linux之后,就能很容易地从大小上分辨出Linux分区。另一个分辨Linux分区的提示是找没有文件系统以及驱动器卷标的分区。Windows分区通常用卷标进行标记,比如C,D,E等等,而且通常是NTFS或FAT文件系统。就像你所能看到的,我在这里有三个Linux分区,因为我在安装Ubuntu时单独地创建了根分区(root),交换分区(swap)和家目录(home)。Step 3: 第三步:选择Linux分区,右键点击并选择 删除卷 选项。假如出现了警告,在这里选择是即可。Step 4: 第四步:被删除的分区会变成一块可用的空闲空间。你可以用它来扩展已有的卷或创建一个新的Windows分区。我会建议你创建一个新的驱动器(或是卷或者分区,随便你怎么叫),因为这样子万一你将来又想将Linux和Winodws双启动时会简单一点。第二部分:修复Windows启动引导一旦你删除了Linux分区,就是时候修复Windows启动引导了。这里的图片看起来可能不是很清楚,因为相对于Windows来说在Ubuntu下对登录画面进行截图要简单的多。我用手机相机拍下了这些照片。第一步:插入Windows 8安装介质并重启你的电脑。在启动的时候按下F10或F12进入BIOS/UEFI,选择从可移除介质启动(boot from removable disk)。第二步:选择修复你的计算机(repair your computer):第三步:在这里选择疑难解答(Troubleshoot):第四步:在疑难解答页面,选择高级选项(Advanced options):第五步:找到这里的命令提示符(command prompt):第六步:在命令行中输入下列命令来修复Windows启动引导:bootrec.exe /fixmbr正常情况下,它是立即生效的,你甚至都不用等。第七步:一旦完成了这一步,重启你的电脑,这次从硬盘正常启动。你应该能够启动进入Windows。假如你仍然看到Grub rescue错误,试试下面的步骤。第八步:假如第六步中的方法不起作用假如第六步中的命令不起作用,试试高级疑难解答中的自动修复选项。它会花点时间查找问题然后修复它。现在假如你重启的话,你应该能够正常进入Windows,不再看到任何的Grub rescue错误提示。我希望这个指南能够帮助你将Ubuntu从Windows 8双启动中完全移除。欢迎提出任何问题与建议。谢谢阅读,希望能帮到大家,请继续关注脚本之家,我们会努力分享更多优秀的文章。

热门资讯