在之前三篇,我们分享的就是需求的分析,基本接口的整理,数据库链接的配置。这次我们分享项目的基本框架,目录结构大致如下:
common目录:
通用目录,放一些通用的处理
models目录:
数据库表模型放在这里(你也可以把数据库相关的都放在这个目录下)
routers目录:
放所有接口的地方
test目录:
放测试用例的地方
settings目录:
放配置文件的地方
middlewares目录:
放所有中间件的地方,比如mysql,redis,mongodb等(主要是数据库操作相关)
Dockerfile:
docker打包文件
main:
程序运行主文件
整体的架构设计完毕后,就可以进行相关开发了,这里我们把之前设计的数据库模型相关放到modles目录下的modles.py下:
"""
-*- encoding=utf-8 -*-
Time: 2024/7/19 14:18
Author: lc
Email: 15101006331@163.com
File: models.py
"""
from sqlalchemy import Column, Integer, String, ForeignKey, Boolean, Text, DateTime
from sqlalchemy import MetaData
from sqlalchemy.inspection import inspect
from datetime import datetimefrom sqlalchemy.orm import DeclarativeMetafrom middlewares.mysql.database import Base, engineclass Role(Base):"""角色"""__tablename__ = "roles"id = Column(Integer, primary_key=True, index=True)name = Column(String(length=8), unique=True, index=True) # 角色名称class User(Base):"""用户基础表"""__tablename__ = "users"id = Column(Integer, primary_key=True, index=True)username = Column(String(length=32), unique=True, index=True) # 用户名password = Column(String(length=252)) # 密码status = Column(Integer, default=0) # 删除,0正常job_num = Column(Integer, nullable=True) # 工号student_num = Column(Integer, nullable=True) # 学号age = Column(Integer) # 年龄sex = Column(String(length=8), default="男") # 性别role = Column(Integer, ForeignKey('roles.id')) # 角色add_time = Column(DateTime, default=datetime.now())class Course(Base):"""课程"""__tablename__ = "courses"id = Column(Integer, primary_key=True, index=True)name = Column(String(length=252), unique=True, index=True) # 课程名称icon = Column(String(length=252), nullable=True) # icondesc = Column(String(length=252), nullable=True) # 描述status = Column(Boolean, default=False) # 状态onsale = Column(Boolean, default=False) # 是否上架catalog = Column(Text, nullable=True) # 目录owner = Column(Integer, ForeignKey('users.id')) # 拥有者like_num = Column(Integer, default=0) # 点赞class StudentCourse(Base):"""学生课程"""__tablename__ = "student_courses"id = Column(Integer, primary_key=True, index=True)student = Column(Integer, ForeignKey('users.id')) # 学生course = Column(Integer, ForeignKey('courses.id')) # 课程add_time = Column(DateTime, default=datetime.now())update_time = Column(DateTime, default=datetime.now())status = Column(Integer, default=0) # 1.删除,0.正常class CourseComment(Base):"""课程评论"""__tablename__ = "course_comments"id = Column(Integer, primary_key=True, index=True)course = Column(Integer, ForeignKey('courses.id')) # 课程user = Column(Integer, ForeignKey('users.id')) # 评论人pid = Column(Integer) # 回复add_time = Column(DateTime, default=datetime.now())top = Column(Boolean, default=False) # 是否置顶context = Column(Text)status = Column(Boolean, default=0) # 1删除0正常class Message(Base):__tablename__ = "messages"id = Column(Integer, primary_key=True, index=True)send_user = Column(Integer, ForeignKey('users.id')) # 发送者accept_user = Column(Integer, ForeignKey('users.id')) # 接收者read = Column(Boolean, default=False) # 是否已读,接收者是否已读send_time = Column(String(length=252)) # 发送时间pid = Column(Integer) # 回复者add_time = Column(DateTime, default=datetime.now()) # 添加时间context = Column(Text)status = Column(Integer, default=0) # 1删除0正常def create_tables():global_dict = globals()classes = [vfor k, v in global_dict.items()if callable(v) and isinstance(v, DeclarativeMeta) and hasattr(v, "__tablename__")]metadata = MetaData()for _cls in classes:if not inspect(engine).has_table(_cls.__tablename__, schema=None, metadata=metadata):_cls.__table__.create(bind=engine)print(f"表:‘{_cls.__tablename__}’ 创建完成!")else:print(f"表:‘{_cls.__tablename__}’ 已存在!")if __name__ == '__main__':create_tables()
之前配置的链接mysql数据库的配置放在对应的database.py中
"""
-*- encoding=utf-8 -*-
Time: 2024/7/19 14:22
Author: lc
Email: 15101006331@163.com
File: database.py
"""
from sqlalchemy import create_engine
from sqlalchemy.orm import declarative_base, sessionmaker
from settings.config import MYSQL_CONFIGconn = "mysql+pymysql://{username}:{password}@{host}:{port}/{database}?charset=utf8".format(username=MYSQL_CONFIG["username"], password=MYSQL_CONFIG["password"], host=MYSQL_CONFIG["host"],port=MYSQL_CONFIG["port"], database=MYSQL_CONFIG["database"])
engine = create_engine(conn)# 该类的每个实例都是一个数据库会话,该类本身还不是数据库会话,但是一旦我们创建了SessionLocal的实例,这个实例将是实际的数据库会话
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)# 创建数据库基类
Base = declarative_base()def create_db():"""每个请求处理完毕后关闭当前连接,不同的请求使用不同的链接"""db = SessionLocal()try:yield dbfinally:db.close()
接下来我们的开发只需要关注主逻辑的处理即可,准备放到对应的crud.py和schemas.py文件中,其中crud主要是逻辑处理详细代码,schemas中主要是参数模型以及响应结果模型。
common中我们对json和log做了统一的处理,对应可以参考:
FastAPI 学习之路(五十九)封装统一的json返回处理工具
FastAPI 学习之路(六十)打造系统的日志输出