第一篇的时候说到,使用的POSTgresql数据库来实现!我仔细想想!丫的我一定是蛋疼!重新换一个数据库干嘛!而且是试了试异步的mysql,再结合的sqlalchemy异步的时候,有点小失望!可能是库的还不兼容,或者我姿势不对,也暂时不想浪费太多的时间,所以还是集中火力再迁移的事上!
哈哈!
所以现在变为了:
fastapi+mysql+sqlalchemy且是的同步的姿势!
本水文篇主要内容:
启动前端 快速进行数据库模型生成 修改前端请求接口 编写后端证码接口
1 前端模板的启动
下载地址:https://gitee.com/big-hedgehog/aidex-sharp
打开项目:
配置自己后端接口API:
修改里面的VUE_APP_BASE_API为自己的地址
VUE_APP_BASE_API=http://127.0.0.1:9889/api
项目依然安装:
yarn install
项目启动:
yarn run serve
前端模板访问
2 后端数据模型的生成
下载地址:https://gitee.com/big-hedgehog/aidex-sharp 1:导入aidex-sharp项目中的SQL文件到mysql数据库:
2:使用sqlacodegen生成对应的数据模型:
sqlacodegen --outfile=models.py mysql://root:123456@localhost:3306/aidex
最终模型如下:
# coding: utf-8
from sqlalchemy import CHAR, Column, DECIMAL, Date, DateTime, Float, ForeignKeyConstraint, Index, LargeBinary, String, Text, text
from sqlalchemy.dialects.mysql import BIGINT, INTEGER, LONGBLOB, SMALLINT, TINYINT, VARCHAR
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.orm import sessionmaker
Base = declarative_base()
# DB_URI = f'mysql+pymysql://root:123456@localhost:3306/aidex'
# sqlacodegen --outfile=models.py mysql://root:123456@localhost:3306/aidex
# 作数据库时报警告Warning: (1366,
metadata = Base.metadata
class BaseTable(Base):
__tablename__ = 'base_table'
__table_args__ = {'comment': '基础表'}
id = Column(String(50), primary_key=True, comment='主键ID')
sort = Column(INTEGER(4), nullable=False, comment='排序')
status = Column(CHAR(1), nullable=False, server_default=text("'0'"), comment='状态(0正常 1 停用)')
create_by = Column(String(64), comment='创建者')
create_dept = Column(String(64), comment='创建部门')
create_time = Column(DateTime, comment='创建时间')
update_by = Column(String(64), comment='更新者')
update_time = Column(DateTime, comment='更新时间')
update_ip = Column(String(128), comment='更新IP')
remark = Column(String(500), comment='备注')
version = Column(INTEGER(11), comment='版本')
del_flag = Column(CHAR(1), server_default=text("'0'"), comment='删除标志(0存在 1删除)')
extend_s1 = Column(String(200), comment='备用字符串1')
extend_s2 = Column(String(200), comment='备用字符串2')
extend_s3 = Column(String(200), comment='备用字符串3')
extend_s4 = Column(String(200), comment='备用字符串4')
extend_i1 = Column(INTEGER(11), comment='备用整型1')
extend_i2 = Column(INTEGER(11), comment='备用整型2')
extend_i3 = Column(INTEGER(11), comment='备用整型3')
extend_i4 = Column(INTEGER(11), comment='备用整型4')
extend_d1 = Column(DateTime, comment='备用日期1')
extend_d2 = Column(DateTime, comment='备用日期2')
extend_d3 = Column(DateTime, comment='备用日期3')
extend_d4 = Column(DateTime, comment='备用日期3')
extend_f1 = Column(Float(11, True), comment='备用浮点1')
extend_f2 = Column(Float(11, True), comment='备用浮点2')
extend_f3 = Column(Float(11, True), comment='备用浮点3')
extend_f4 = Column(Float(11, True), comment='备用浮点4')
class BaseTreeTable(Base):
__tablename__ = 'base_tree_table'
__table_args__ = {'comment': '树基础表'}
id = Column(String(32), primary_key=True, comment='部门id')
parent_id = Column(String(32), server_default=text("'0'"), comment='父id')
parent_ids = Column(String(500), comment='父id集合')
tree_sort = Column(INTEGER(11), server_default=text("'0'"), comment='排序')
tree_sorts = Column(String(500), comment='排序集合')
tree_level = Column(INTEGER(11), comment='层级')
tree_leaf = Column(CHAR(1), comment='是否子节点(0是 1否)')
status = Column(CHAR(1), server_default=text("'0'"), comment='状态(0正常 1停用)')
create_by = Column(String(64), comment='创建者')
create_dept = Column(String(64), comment='创建部门')
create_time = Column(DateTime, comment='创建时间')
update_by = Column(String(64), comment='更新者')
update_time = Column(DateTime, comment='更新时间')
update_ip = Column(String(128), comment='更新IP')
remark = Column(String(500), comment='备注')
version = Column(INTEGER(11), comment='版本')
del_flag = Column(CHAR(1), server_default=text("'0'"), comment='删除标志(0代表存在 1代表删除)')
·······省略一大批代码
编写一个客户端测试链接数据库验证:
#!/usr/bin/evn python
# -*- coding: utf-8 -*-
"""
-------------------------------------------------
文件名称 : async_client
文件功能描述 : 功能描述
创建人 : 小钟同学
创建时间 : 2021/10/22
-------------------------------------------------
修改描述-2021/10/22:
-------------------------------------------------
"""
from sqlalchemy.ext.mutable import Mutable
from sqlalchemy.orm import DeclarativeMeta
from sqlalchemy import create_engine, event, cast
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.ext.asyncio import create_async_engine
from sqlalchemy.orm import scoped_session
from sqlalchemy.orm import sessionmaker
from sqlalchemy.dialects.postgresql import ARRAY
from contextlib import asynccontextmanager
from typing import AsyncGenerator, Any
from sqlalchemy.exc import SQLAlchemyError
DB_URI = f'mysql+mysqlconnector://root:123456@localhost:3306/aidex'
engine = create_engine(DB_URI)
db_session = scoped_session(sessionmaker(bind=engine, expire_on_commit=True))
def GetSession():
return db_session()
from contextlib import contextmanager
@contextmanager
def session_scope():
session = GetSession()
try:
yield session
session.commit()
except:
session.rollback()
raise
finally:
session.close()
if __name__ == '__main__':
from app.admin.models.modelsmysql import SysUser
with session_scope() as session:
item_list = session.query(SysUser).all()
print(item_list)
for item in item_list:
print(item.name)
3 后端验证码接口
基础准备
后端的话,基于自己的之前开源的脚手架模板,稍作调整修改为如下的结构:
所有的后台的接口的,我的统一的放到admin模块下面进行管理:
关于模块的批量加载的,套路还是之前说的:
首先统一我们的API接口的前缀:
写一个生成验证码的接口:
首先修改验证码生成接口的工具类,修改使用的字体:
编写生成验证码接口代码:
完整代码验证码生产接口:
#!/usr/bin/evn python
# -*- coding: utf-8 -*-
"""
-------------------------------------------------
文件名称 : captcha
文件功能描述 : 功能描述
创建人 : 小钟同学
创建时间 : 2021/10/28
-------------------------------------------------
修改描述-2021/10/28:
-------------------------------------------------
"""
from app.admin.api import bp as lantu
from io import BytesIO
from app.utils.captcha_helper import Captcha
from starlette.responses import StreamingResponse
import io
@lantu.get("/captchaImage", summary="获取验证码-【小钟】")
def captcha():
"""
使用定义好的图形验证码类,来制作验证码
以验证码为键、验证码为值(为了用户的体验,让其忽略大小写)存储在redis缓存中
通过BytesIO字节流的方式保存和访问图片
:return: 图片响应
"""
# 第一个版本的
text, image = Captcha().gen_graph_captcha()
out = BytesIO()
image.save(out, 'png')
out.seek(0)
return StreamingResponse(BytesIO(out.read()), media_type="image/png")
# 用于判断文件后缀
@lantu.get("/captchaImage/{niums}", summary="随机验证码图-【小钟】")
async def randomImage(niums):
"""
图片验证码
:param niums:
:return:
"""
# 第一个版本的
text, image = Captcha().gen_graph_captcha()
out = BytesIO()
image.save(out, 'png')
out.seek(0)
return StreamingResponse(io.BytesIO(out.read()), media_type="image/png")
反问生成验证码接口:
查看前端的显示:
修改前端代码,让它可以直接的显示输出文件流图片:
然后修改登入的地方:
然后查看前端访问的情况:
最后再说一下:如果大家感兴趣的!赶紧的给做一个star吧!非常nine的!虽然当前这模板多多少少有点小问题,但是她一直再努力进行优化中!
结尾
END
简书:https://www.jianshu.com/u/d6960089b087
掘金:https://juejin.cn/user/2963939079225608
公众号:微信搜【小儿来一壶枸杞酒泡茶】
小钟同学 | 文 【欢迎一起学习交流】| QQ:308711822
1:本文相关描述主要是个人的认知和见解,如有不当之处,还望各位大佬指正。 2:关于文章内容,部分内容参考自互联网整理,如有链接会声明标注;如没有及时标注备注的链接的,如有侵权请联系,我会立即删除处理哟。