技术文章如何写作才能有较好的阅读体验

派盖褪秘1、FastAPI实现主从表数据接口和SqlAlchemy的数据处理

WxPython跨平台开发框架全部采用Python语言进行开发,包括后端的内容,采用 基于SqlAlchemy+Pydantic+FastApi 的后端框架,FastAPI启动后,进入Swagger页面如下所示,列出每个业务表的相关接口。

以上就是常规化的接口,包括单个获取、ID存在、条件查询、分页查询、数量查询、增加、删除、更新等标准化接口,这些基础类接口一般封装在API的控制器基类中。

该后端接口采用统一的接口协议,标准协议如下所示。

复制代码

{

"success": false,

"result": T ,

"targetUrl": "string",

"UnAuthorizedRequest": false,

"errorInfo": {

"code": 0,

"message": "string",

"details": "string"

}

}

复制代码

常规化的接口是结合泛型的方式,这样定义可以很好的抽象不同的业务类接口到基类控制器中,如下是FastApi 后端的基类控制器定义。

image

有了上面基类定义好的常规化接口,子类只需要继承基类控制器即可获得强大的功能接口了。

一般API控制器的子类,只需要继承基类就可以了,额外增加的接口按常规化的设计函数即可,可以参考基类的做法来写各种(GET、PUT、DELETE、POST)的处理函数。

image

我们来看看对于产品报价单和明细记录的处理,这两个代表不同的业务表,我们可以分开管理,通过约束他们的记录关系实现主从表弹性化的管理。

如对于主表,我们在基类接口外定义多两个函数,主要就是删除主表的时候,同时移除明细记录的关联操作。

复制代码

from fastapi import APIRouter, Depends, HTTPException, Query, Request, Path, Body

..................

# 创建路由,用于处理自定义接口

router = APIRouter()

@router.get(

"byorderno/{orderno}",

response_model=AjaxResponse[QuotationDto | None],

summary="根据报价单编号获取对象信息",

dependencies=[DependsJwtAuth],

)

async def find_by_orderno(

orderno: Annotated[str | None, Path(description="订单编号")],

request: Request,

db: AsyncSession = Depends(get_db),

):

# ip = await get_request_ip(request)

item = await quotation_crud.get_by_column(db, "handno", orderno)

item = QuotationDto.model_validate(item) if item else None

return AjaxResponse(item)

@router.delete(

"quotation-related/{id}",

response_model=AjaxResponse[bool | None],

summary="删除报价单及明细信息",

dependencies=[DependsJwtAuth],

)

async def delete_quotation_related(

id: Annotated[str | None, Path(description="报价单ID")],

request: Request,

db: AsyncSession = Depends(get_db),

):

# ip = await get_request_ip(request)

#获取记录信息

item = await quotation_crud.get(db, id)

if not item:

return AjaxResponse(False)

# 删除相关的明细记录

res = await quotationdetail_crud.delete_by_column(db, "orderno", item.handno)

if res:

# 再删除报价单

await quotation_crud.delete_byid(db, id)

return AjaxResponse(res)

# 使用基类控制器,可以继承常规CRUD的接口,并自动生成路由,依赖注入,数据库连接等功能 ——构建方式2

controller = BaseController[Quotation, str, QuotationPageDto, QuotationDto](

quotation_crud,

pagedto_class=QuotationPageDto,

dto_class=QuotationDto,

router=router,

)

controller.init_router() # 初始化常规CRUD等接口的路由

复制代码

而报价单明细业务控制器,主要需要根据报价单号(订单号)获取明细的接口

复制代码

from fastapi import APIRouter, Depends, HTTPException, Query, Request, Path, Body

from typing import Type, TypeVar, Generic, List, Dict, Any, Optional, Annotated

from datetime import datetime

from sqlalchemy.ext.asyncio import AsyncSession

from schemas.base import AjaxResponse, ErrorInfo, ListResult, PagedResult

from api.base_controller import BaseController

from db.session_async import get_db

from common.jwt import DependsJwtAuth

from models.quotationdetail import QuotationDetail

from schemas.quotationdetail import QuotationDetailDto, QuotationDetailPageDto

from crud.quotationdetail import quotationdetail as quotationdetail_crud

from crud.operationlog import operationlog as operationlog_crud

from utils.request_parse import get_request_ip

# 创建路由,用于处理自定义接口

router = APIRouter()

@router.get(

"/by-orderno",

response_model=AjaxResponse[List[QuotationDetailDto] | None],

summary="根据订单编号获取记录",

dependencies=[DependsJwtAuth],

)

async def get_by_orderno(

orderno: Annotated[str | None, Query(description="订单编号")],

request: Request,

db: AsyncSession = Depends(get_db),

):

# ip = await get_request_ip(request)

items = await quotationdetail_crud.get_by_orderno(db, orderno)

# print(len(items))

items = [QuotationDetailDto.model_validate(item) for item in items]

return AjaxResponse(items)

@router.delete(

"/by-orderno/{orderno}",

response_model=AjaxResponse[bool | None],

summary="根据订单编号删除所有明细记录",

dependencies=[DependsJwtAuth],

)

async def delete_by_orderno(

orderno: Annotated[str | None, Path(description="订单编号")],

request: Request,

db: AsyncSession = Depends(get_db),

):

res = await quotationdetail_crud.delete_by_attributes(db, QuotationDetail.orderno == orderno)

return AjaxResponse(res)

# 使用基类控制器,可以继承常规CRUD的接口,并自动生成路由,依赖注入,数据库连接等功能

controller = BaseController[QuotationDetail, str, QuotationDetailPageDto, QuotationDetailDto](

quotationdetail_crud,

pagedto_class=QuotationDetailPageDto,

dto_class=QuotationDetailDto,

router=router,

)

controller.init_router() # 初始化常规CRUD等接口的路由

复制代码

由于基类控制器接口的标准化,我们根据框架后端的接口进行前端API调用类的封装处理,从而实现业务基类调用接口的统一封装,简化代码。这样增删改查等处理的接口都可以抽象到BaseApi里面了。

如对于权限模块,我们涉及到的用户管理、机构管理、角色管理、菜单管理、功能管理、操作日志、登录日志等业务类,那么这些类继承BaseApi,就会具有相关的接口了,如下所示继承关系。

2、基于SqlAlchemy实现的业务模型

FastAPI负责提供数据的API接口,底层的数据处理,通过SqlAlchemy + MongoDB 实现多种数据库的数据管理,如对于MySQL、Postgresql、SQLite、Oracle、MongoDB等进行接入和数据交换处理。

对于常规的业务表,我们采用SqlAlchemy实现数据库的ORM管理的,SqlAlchemy也是Python领域中非常强大的ORM管理模块之一, 它让你用 Python 对象来操作数据库,而不是手写 SQL 语句。

一般我们先定义好模型的基类,提供简单的封装

image

然后在业务类里面继承它即可

image

报价单的明细表也是类似的

image

这些模型类和对应接口的DTO类只需要在代码生成工具中进行一键生成就可以了,不用编写。

在代码生成工具 Database2Sharp 打开数据库列表后,右键菜单可以选择生成对应的Python+FastApi后端项目,如下界面所示。

选中相关的表后,一键可以生成各层的类文件,其中包括最为繁琐的Model映射类信息。如下是生成的相关类的界面效果。

2、WxPthon实现基于Python桌面端主从表的数据处理

我们知道,一般对于单表来说,业务和界面会相对比较简单,如下面的界面效果,在Windows下客户信息的列表管理和数据编辑界面如下所示。

而对于主从表,一般除了主业务表外,会关联一个到多个的明细表,对于报价单来说,就只有一个明细表,如下所示是具体的界面列表展示。

image

对于列表的主从表关联关系,没有太多好说的,就是增加了一个明细表的处理展示

对于主从表编辑界面来说,就需要复杂处理一些,在表格需要直接编辑录入并保存明细的操作处理,如下是主从表的编辑界面的实现效果。

image

其主要就是在第一次创建的时候,对表格数据类进行设置

image

表格的数据直接录入,一般不是仅仅的通过文本框的录入,一般录入有选择表的记录,下拉类表、复选框、图像、数值、颜色等等特殊的录入的。

如自定义数据列表选择界面,我通过定义一个产品的数据列表展示供选择,单击产品编码处,弹出一个选择框进行选择。

image

为了实现对表格数据单元格的单击监控,我们绑定了对应的事件。

AsyncBind(wx.grid.EVT_GRID_CELL_LEFT_CLICK, self.on_cell_left_click, self.sub_grid)

然后对事件进行实现即可。

image

下拉列表则是通过绑定固定列表,或者字典类型的方式实现字典下拉列表选择

image

初始化字典列表很容易,如下代码所示。

image

其他案例可以参考测试效果,支持多种数据输入处理,测试界面效果如下所示。

image

关于 阿里云盘CLI。仿 Linux shell 文件处理命令的阿里云盘命令行客户端,支持JavaScript插件,支持同步备份功能,支持相册批量下载。 特色 多平台支持, 支持 Windows, macOS, linux(x86/x64/arm), android, iOS 等 阿里云盘多用户支持 支持备份盘,资源库无缝切换 下载网盘内文件, 支持多个文件或目录下载, 支持断点续传和单文件并行下载。支持软链接(符号链接)文件。 上传本地文件, 支持多个文件或目录上传,支持排除指定文件夹/文件(正则表达式)功能。支持软链接(符号链接)文件。 同步备份功能支持备份本地文件到云盘,备份云盘文件到本地,双向同步备份保持本地文件和网盘文件同步。常用于嵌入式或者NAS等设备,支持docker镜像部署。 命令和文件路径输入支持Tab键自动补全,路径支持通配符匹配模式 支持JavaScript插件,你可以按照自己的需要定制上传/下载中关键步骤的行为,最大程度满足自己的个性化需求 支持共享相册的相关操作,支持批量下载相册所有普通照片、实况照片文件到本地 支持多用户联合下载功能,对下载速度有极致追求的用户可以尝试使用该选项。详情请查看文档多用户联合下载 如果大家有打算开通阿里云盘VIP会员,可以使用阿里云盘APP扫描下面的优惠推荐码进行开通。 注意:您需要开通【三方应用权益包】,这样使用本程序下载才能加速,否则下载无法提速。 Windows不第二步打开aliyunpan命令行程序,任何云盘命令都有类似如下日志输出 如何登出和下线客户端 阿里云盘单账户最多只允许同时登录 10 台设备 当出现这个提示:你账号已超出最大登录设备数量,请先下线一台设备,然后重启本应用,才可以继续使用 说明你的账号登录客户端已经超过数量,你需要先登出其他客户端才能继续使用,如下所示
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值