分享

python:Fastapi - SQL(关系)数据库

 只怕想不到 2022-03-28

Fastapi可关联市场的主流数据库,下面主要是结合sqlalchemy操作mysql数据库。当然你也可以使用SQLite,因为它使用单个文件并且 Python 具有集成支持。操作起来更简单,坑也少一点。

话不多说,下面进入正题


首先得要先安装:

1.    pip install sqlalchemy

工程目录中新建sql_app包,可以理解是一个小的数据库操作包

1.    sql_app
2.    ├── __init__.py
3.    ├── crud.py
4.    ├── database.py
5.    ├── main.py
6.    ├── models.py
7.    └── schemas.py

文件注释:

  • __init__.py是包文件,暂时不用理会

  • crud.py是放置执行数据操作的函数

  • database.py是连接数据库,并进行初始化

  • main.py是放置接口,也是文件的主入口

  • models.py是创建模型属性的,主要是针对数据库创建字段和表

  • schemas.py是创建模型,也就是接口传的一些参数

database.py文件中的数据:

1.    #!/usr/bin/env python
2.    # -*- coding: utf-8 -*-
3.    # @Time    : 2022/2/23 14:13
4.    # @Author  : Lifeng
5.    # @Site    :
6.    # @File    : database.py
7.    # @Software: PyCharm
8.    
9.     from sqlalchemy import create_engine
10.    from sqlalchemy.ext.declarative import declarative_base
11.    from sqlalchemy.orm import sessionmaker
12.    
13.    __all__ = ['BASE''get_db']
14.    
15.    
16.    class _DBConnect:
17.        # 定义一个变量
18.        # _SQLALCHEMY_DATABASE_URL = 'sqlite:///./sqlite_database.db'
19.        _SQLALCHEMY_DATABASE_URL = 'mysql+pymysql://root:123456@192.168.0.111:3306/fastapi-dev?charset=utf8'
20.        # SQLALCHEMY_DATABASE_URL = 'postgresql://user:password@postgresserver/db'
21.    
22.        # 创建一个连接
23.        _engine = create_engine(
24.            _SQLALCHEMY_DATABASE_URL
25.        )
26.    
27.        # 创建一个持久对象,好处就是可以一次添加多个对象
28.        SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=_engine)
29.    
30.        # 定义一个ORM模型基类
31.        Base = declarative_base()
32.        # 绑定连接,使用表元数据和引擎
33.        Base.metadata.create_all(bind=_engine)
34.    
35.    
36.    # _DBConnect.Base赋值给BASE变量
37.    BASE = _DBConnect.Base
38.    
39.    
40.    def get_db():
41.        '''
42.        初始化持久对象,并yield返回
43.        无论失败与否最后都会调用关闭
44.        :return:
45.        '''

46.        db = _DBConnect.SessionLocal()
47.        try:
48.            yield db
49.        finally:
50.            db.close()

注释信息:

  • get_db函数因为后续要做全局使用,可以考虑做成中间件使用,但是中间件的使用没有yield操作快

models.py文件中的数据:

1.    #!/usr/bin/env python
2.    # -*- coding: utf-8 -*-
3.    # @Time    : 2022/2/23 14:13
4.    # @Author  : Lifeng
5.    # @Site    :
6.    # @File    : models.py
7.    # @Software: PyCharm
8.    
9.     from sqlalchemy import Boolean, Column, ForeignKey, Integer, String
10.    from sqlalchemy.orm import relationship
11.    from .database import BASE
12.    
13.    
14.    class User(BASE):
15.        __tablename__ = 'users'
16.    
17.        id = Column(Integer, primary_key=True, index=True)
18.        email = Column(String, unique=True, index=True)
19.        password = Column(String)
20.        is_active = Column(Boolean, default=True)
21.    
22.        items = relationship('Item', back_populates='owner')
23.    
24.    
25.    class Item(BASE):
26.        __tablename__ = 'items'
27.    
28.        id = Column(Integer, primary_key=True, index=True)
29.        title = Column(String, index=True)
30.        description = Column(String, index=True)
31.        owner_id = Column(Integer, ForeignKey('users.id'))
32.    
33.        owner = relationship('User', back_populates='items')

注释信息:

  • __tablname__是指定表名

  • idemailpasswordis_active是指定数据库中users表的一些字段

  • owner_id是设置成表的的外键,关联住users表中的主键id

  • relationship是进行两表关联,也就是一对一

注意点:如果你连接的是mysql数据库,那要先在库中手动建好users表和items表,不然直接运行就会报错

schemas.py文件中的数据:

1.    #!/usr/bin/env python
2.    # -*- coding: utf-8 -*-
3.    # @Time    : 2022/2/23 14:13
4.    # @Author  : Lifeng
5.    # @Site    :
6.    # @File    : schemas.py
7.    # @Software: PyCharm
8.    
9.     from typing import List, Optional
10.    
11.    from pydantic import BaseModel
12.    
13.    
14.    class Items(BaseModel):
15.        title: str
16.        description: Optional[str] = None
17.    
18.    
19.    class Item(Items):
20.        id: int
21.        owner_id: int
22.    
23.        class Config:
24.            orm_mode = True
25.    
26.    
27.    class Users(BaseModel):
28.        email: str
29.    
30.    
31.    class UserCreate(Users):
32.        password: str
33.    
34.    
35.    class User(Users):
36.        id: int
37.        is_active: bool
38.        items: List[Item] = []
39.    
40.        # 向 Pydantic 提供配置
41.        class Config:
42.            orm_mode = True

注释信息:

  • orm_mode=True是允许ORM模式,Pydantic 模型可以从任意类实例创建以支持映射到 ORM 对象的模型。

注意点: 参数orm_mode必须是True,否则会报错

crud.py文件中数据:

1.    #!/usr/bin/env python
2.    # -*- coding: utf-8 -*-
3.    # @Time    : 2022/2/23 14:13
4.    # @Author  : Lifeng
5.    # @Site    :
6.    # @File    : crud.py
7.    # @Software: PyCharm
8.    
9.     from sqlalchemy.orm import Session
10.    from . import models, schemas
11.    
12.    
13.    def get_user_by_email(db: Session, email: str):
14.        return db.query(models.User).filter(models.User.email == email).first()
15.    
16.    
17.    def get_users(db: Session, skip: int = 0, limit: int = 100):
18.        return db.query(models.User).offset(skip).limit(limit).all()
19.    
20.    
21.    def create_user(db: Session, user: schemas.UserCreate):
22.        fake_hashed_password = user.password + 'notreallyhashed'
23.        db_user = models.User(email=user.email, password=fake_hashed_password)
24.        db.add(db_user)
25.        db.commit()
26.        db.refresh(db_user)
27.        return db_user

注释信息:

  • get_user_by_email函数和get_users函数均是从数据库获取数据

  • create_user函数是创建数据,并对密码进行加密后提交至数据库表中

后续补充:这里是sqlalchemy库的一些语法,后续会单独开一篇来总结下语法实际操作

main.py文件中的数据:

1.    #!/usr/bin/env python
2.    # -*- coding: utf-8 -*-
3.    # @Time    : 2022/2/23 14:13
4.    # @Author  : Lifeng
5.    # @Site    :
6.    # @File    : main.py
7.    # @Software: PyCharm
8.    
9.     import uvicorn
10.    from typing import List
11.    from sqlalchemy.orm import Session
12.    from sql_app import crud, schemas
13.    from sql_app.database import get_db
14.    from fastapi import Depends, FastAPI, HTTPException
15.    
16.    app = FastAPI()
17.    
18.    
19.    @app.post('/users/', response_model=schemas.User)
20.    def create_user(user: schemas.UserCreate, db: Session = Depends(get_db)):
21.        db_user = crud.get_user_by_email(db, email=user.email)
22.        if db_user:
23.            raise HTTPException(status_code=400, detail='Email already registered')
24.        return crud.create_user(db=db, user=user)
25.    
26.    
27.    @app.get('/users/', response_model=List[schemas.User])
28.    def read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
29.        users = crud.get_users(db, skip=skip, limit=limit)
30.        return users
31.    
32.    
33.    if __name__ == '__main__':
34.        uvicorn.run('main:app', debug=True)

注释信息:

  • main.py文件中的都是以前的一些内容了,就不再多陈述了

  • Depends(get_db)是作依赖项,db: Session是关联到ORM会话


接口启动服务后,打开postman工具进行接口请求

POST http://127.0.0.1:8000/users

请求参数:

{
    'email''debugfeng02@qq.com',
    'password''123456'
}

请求结果:

{
    'email''debugfeng02@qq.com',
    'id'6,
    'is_active'true,
    'items': []
}

写入结果:

图片


微信号:debugfeng
文章作者:李锋;编辑排版:梁莉莉

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多