21.FastAPI关系型数据处理

21.FastAPI关系型数据处理

在FastAPI应用程序开发中,不可避免要使用关系型数据库,FastAPI本身并不要求使用关系型数据库。但在开发中可以根据自己的需求使用任何关系型数据库。这里,我们以PostgreSQL数据库及SQLAlchemy为例来说明在FastAPI应用程序开发中使用数据库的方法。

在本例中,实现一个通讯录的管理和维护,包括通讯录的增删改查操作。该例不使用ORM来实现,以原生SQL +SQLALchemy的方式来实现,SQLALchemy只用于执行SQL语句,不使用其ORM的方式。

21.1设计并创建数据表

create table test.d_address_book(
    address_book_id varchar(64) primary key,  --id
    name varchar(32),  --姓名
    sex varchar(2),  --性别
    mobile varchar(16),  --手机号码
    email varchar(256),  --电子邮箱
    qq varchar(32),  --QQ号
    com_name varchar(128), --单位名称
    post_address varchar(256),  --通讯地址
    remarks varchar(256)  --备注
);

21.2创建pydantic模型

class AddressBook(BaseModel):
    address_book_id: Optional[str] = None
    name: str = Field(...)
    sex: str = Field(...)
    mobile: str = Field(...)
    email: str = Field(...)
    qq: str = Field(...)
    com_name: str = Field(...)
    post_address: str = Field(...)
    remarks: Optional[str] = None

上面的pydantic模型与数据库表test.d_address_book的字段名保持一致。

21.3建立数据库连接

在项目中新建一个database.py文件,用于连接数据库,代码如下:

# coding: utf-8
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
​
# 数据库连接url
SQLALCHEMY_DATABASE_URL = "postgresql://postgres:jane10181010@127.0.0.1:9432/qydb"
​
# 创建数据库连接
engine = create_engine(
    SQLALCHEMY_DATABASE_URL,
    echo = True
)
​
# 创建会话
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
​
def getdb():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

上面的代码用于建立数据库连接,使用数据库连接的时候通过getdb()函数获取到数据库会话,然后执行SQL语句。

21.4创建数据

创建数据,即在数据表中插入数据,本例采用执行原生SQL来处理。代码如下:

@app.post(path='/address_book/create')
async def create_address_book(addressbook: AddressBook=Body(...), db: Session=Depends(getdb)):
    res = {'res': True, 'desc': None}
    # 设置主键
    addressbook.address_book_id = str(uuid.uuid1())
    # SQL语句
    sql = '''
    INSERT INTO test.d_address_book
    (address_book_id, name, sex, mobile, email, qq, com_name, post_address, remarks)
    VALUES(:address_book_id, :name, :sex, :mobile, :email, :qq, :com_name, :post_address, :remarks)
    '''
    # 执行SQL语句
    try:
        db.execute(sql, params=addressbook.dict())
        db.commit()
    except Exception as ex:
        db.rollback()
        res['res'] = False
        res['desc'] = str(ex)
        print(ex)
​
    return res

测试请求:

curl -H "Content-Type: application/json" -X POST -d "{\"name\": \"limin\", \"sex\": \"nv\", \"mobile\":\"13904710527\", \"email\":\"liming@163.com\", \"qq\":\"469125782\", \"com_name\":\"Beijing zhong he qing yang ke ji you xian gong si\", \"post_address\":\"Beijing shi hai dian qu chang chun qiao lu xin qi dian jia yuan 12 hao lou 1905\", \"remarks\": null}" http://127.0.0.1:8000/address_book/create
{"res":true,"desc":null}

21.5更新数据

代码如下:

@app.post(path='/address_book/update')
async def update_address_book(addressbook: AddressBook=Body(...), db: Session = Depends(getdb)):
    res = {'res': True, 'desc': None}
    # SQL语句
    sql = '''
    UPDATE test.d_address_book set 
    name=:name, 
    sex=:sex, 
    mobile=:mobile, 
    email=:email, 
    qq=:qq, 
    com_name=:com_name, 
    post_address=:post_address, 
    remarks=:remarks
    where address_book_id=:address_book_id
    '''
    # 执行SQL语句
    try:
        db.execute(sql, params=addressbook.dict())
        db.commit()
    except Exception as ex:
        db.rollback()
        res['res'] = False
        res['desc'] = str(ex)
        print(ex)
​
    return res

测试请求:

curl -H "Content-Type: application/json" -X POST -d "{\"address_book_id\":\"53578e06-8565-11ec-9c53-70c94ec87656\", \"name\": \"hejing\", \"sex\": \"nv\", \"mobile\":\"13904710527\", \"email\":\"liming@163.com\", \"qq\":\"469125782\", \"com_name\":\"Beijing zhong he qing yang ke ji you xian gong si\", \"post_address\":\"Beijing shi hai dian qu chang chun qiao lu xin qi dian jia yuan 12 hao lou 1905\", \"remarks\": null}" http://127.0.0.1:8000/address_book/update
{"res":true,"desc":null}

21.6删除数据

代码如下:

@app.post(path='/address_book/delete')
async def delete_address_book(address_book_id: str=Body(..., embed=True), db: Session = Depends(getdb)):
    res = {'res': True, 'desc': None}
    # SQL语句
    sql = '''
    DELETE from test.d_address_book
    where address_book_id=:address_book_id
    '''
    # 执行SQL语句
    try:
        db.execute(sql, params={'address_book_id': address_book_id})
        db.commit()
    except Exception as ex:
        db.rollback()
        res['res'] = False
        res['desc'] = str(ex)
        print(ex)
​
    return res

需要注意:由于删除数据只提交数据表的主键,所以在参数中使用了Body(..., embed=True)。

测试请求:

curl -H "Content-Type: application/json" -X POST -d "{\"address_book_id\":\"1b43feb4-856a-11ec-a926-70c94ec87656\"}" http://127.0.0.1:8000/address_book/delete
{"res":true,"desc":null}

21.7查询数据

代码如下:

@app.get(path='/address_book/retrieve', response_model=List[AddressBook])
async def retrieve_address_book(db: Session = Depends(getdb)):
    # SQL语句
    sql = '''
    SELECT address_book_id, "name", sex, mobile, email, qq, com_name, post_address, remarks
    FROM test.d_address_book
    '''
    # 执行SQL语句
    rows = []
    try:
        result = db.execute(sql)
        rows = result.fetchall()
    except Exception as ex:
        print(ex)
​
    return rows

上面的代码中,响应模型仍然使用AddressBook,且是AddressBook模型的List,虽然在代码中直接返回了数据集,但通过响应模型的限制可以根据开发需求进行返回数据的限制和管理。

测试请求:

curl http://127.0.0.1:8000/address_book/retrieve
[
    {
        "address_book_id":"19ef0854-8564-11ec-87ac-70c94ec87656",
        "name":"limin",
        "sex":"nv",
        "mobile":"13904710527",
        "email":"liming@163.com",
        "qq":"469125782",
        "com_name":"Beijing zhong he qing yang ke ji you xian gong si",
        "post_address":"Beijing shi hai dian qu chang chun qiao lu xin qi dian jia yuan 12 hao lou 1905",
        "remarks":null
    },{
        "address_book_id":"8d21f814-8564-11ec-b05d-70c94ec87656",
        "name":"limin",
        "sex":"nv",
        "mobile":"13904710527",
        "email":"liming@163.com",
        "qq":"469125782",
        "com_name":"Beijing zhong he qing yang ke ji you xian gong si",
        "post_address":"Beijing shi hai dian qu chang chun qiao lu xin qi dian jia yuan 12 hao lou 1905",
        "remarks":null
    }
]

以上例子没有使用SQLALchemy的ORM方式进行数据处理,同时为了简化开发,在路由方法中直接执行原生SQL来进行数据处理,在实际开发中,可以使用分层模式进行开发。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Janeb1018

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

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

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

打赏作者

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

抵扣说明:

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

余额充值