FastAPI可以和任何数据库和任意样式的库配合使用,这里看一下使用SQLAlchemy的示例。下面的示例很容易的调整为PostgreSQL
,MySQL
,SQLite
,Oracle
等。当前示例中我们使用SQLite
ORM对象关系映射
FastAPI可以与任何数据库在任何样式的库中一起与数据库进行通信。一种常见的模式就是“ORM
”:对象关系映射。所谓对象关系映射就是,ORM具有在代码和数据库表(“关系型”)中的对象中间转换(“映射”)的工具。即使用ORM,在SQL数据库创建一个代表映射的类,该类的每个数据代表数据表中的一个列,具有名称和类型。约定俗成:类使用大写如Pet,代表SQL为表的pets,该累的每个实例对象标识数据库中的一行数据。比如一个对象orion_cat(Pet的一个实例)可以有一个属性orion_cat.type, 对标数据库中的type列。并且该属性的值可以是其它,例如"cat"
文件结构
假设有个fastapi_sqlalchemy的项目,其下有一个包为sql_app,结构如下所示:
fastapi_sqlalchemy
├── sql_app
│ ├── __init__.py
│ ├── crud.py
│ ├── database.py
│ ├── main.py
│ ├── models.py
│ ├── requirements.txt
│ └── schemas.py
└── sql_app.db
既然是sql_app包,肯定少不了__init__.py
,这里的初始化函数为空。其中依赖requirement.txt中为
fastapi==0.111.0
pydantic==2.7.4
SQLAlchemy==2.0.30
📢📢:这里使用的SQLAlchemy 为2.0以上版本,如果使用v1,则有些语法不同。
创建SQLAlchemy部件
首先看一下sql_app/database.py
创建SQLAlchemy引擎和初始化Base类
# @File : database.py
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
SQLALCHEMY_DATABASE_URL = "sqlite:///./sql_app.db"
# SQLALCHEMY_DATABASE_URL = "postgresql://user:password@postgresserver/db"
# 来允许SQLite这样
engine = create_engine(
SQLALCHEMY_DATABASE_URL, connect_args={
"check_same_thread": False}
)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
# 用于建立数据库SQLAlchemy模型models
Base = declarative_base()
创建一个SQLAlchemy 引擎,其中connect_args={“check_same_thread”: False} 仅用于SQLite,其他数据库不需要 。
默认情况下,SQLite 只允许一个线程与其通信,假设有多个线程的话,也只将处理一个独立的请求。这是为了防止意外地为不同的事物(不同的请求)共享相同的连接。但是在 FastAPI 中,使用普通函数(def)时,多个线程可以为同一个请求与数据库交互,所以我们需要使用connect_args={“check_same_thread”: False}来让SQLite允许这样。
此外,我们将确保每个请求都在依赖项中获得自己的数据库连接会话,因此不需要该默认机制。
连接到一个SQLite数据库,该文件在当前目录下的sql_app.db中
创建SessionLocal
的时候,每个 SessionLocal 的类的实例都是一个数据库会话,当然该类本身还不是数据库会话。但是一旦我们创建了一个SessionLocal类的实例,这个实例将是实际的数据库会话。我们将它命名为SessionLocal是为了将它与我们从 SQLAlchemy 导入的Session区别开来。稍后我们将使用Session(从 SQLAlchemy 导入的那个)。要创建SessionLocal类,请使用函数sessionmaker
Base = declarative_base()
,在后面的会继承这个Base类,来创建每个数据库模型或者类(ORM模型)
创建数据库模型models
在文件sql_app/models.py
中,使用上一步创建的Base类派生子类来创建SQLAlchemy模型。
📢📢:
- SQLAlchemy中的“模型”指的的是和数据库交互的类和实例
- Pydantic中的“模型”指的是不同的东西,即数据验证、转换以及文档类和实例
# @File : models.py
from sql_app.database import Base
from sqlalchemy import Boolean, Column, ForeignKey, Integer, String
from sqlalchemy.orm import relationship
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True) # primary_key 为True标识主键
email = Column(String, unique=True, index=True) # unique 如果为True表示这列不允许出现重复的值,index=True为这列创建索引,提升查询效率
hashed_password = Column(String)
is_active = Column(Boolean, default=True) # default=True 为这列设置默认值
items = relationship(