多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

Archery SQLQuery 接口 DRF 迁移指南:统一 6 个 SQL 查询接口的授权、契约与兼容策略

Archery SQLQuery 接口 DRF 迁移指南:统一 6 个 SQL 查询接口的授权、契约与兼容策略 后端数据库【免费下载链接】ArcherySQL 审核查询平台项目地址https://gitcode.com/gh_mirrors/ar/Archery点击查看免费下载导读本文围绕 Archery 开源 SQL 审核查询平台中002-migrate-sqlquery-api特性规格展开系统讲解如何将 SQL 查询页面依赖的实例列表、database 列表、table 列表、执行查询、历史查询记录、收藏 SQL 共 6 个后端交互能力迁移到 Django REST FrameworkDRF统一接口层。读完本文你将掌握迁移的接口清单与边界、按接口收敛的权限模型、请求/响应契约设计、服务层抽取方式、前后端兼容策略以及 pytest-first 的测试组织方法并可直接对照仓库中的 规格文档、OpenAPI 契约 与 实现源码 进行验证。一、迁移背景与规格质量门禁1.1 特性目标该特性Feature Branch002-migrate-sqlquery-drf的原始诉求非常明确将 SQL 查询sqlquery涉及的所有接口改为 DRF 实现以充分利用 DRF 已有的授权配置体系。规格文档 spec.md 将其落成三个可独立交付的用户故事User Story 1P1安全执行查询用户在现有 SQL 查询页面上选择实例、数据库并执行查询请求统一经过标准接口授权与校验保证查询结果、权限判断和安全限制保持一致是迁移的主线MVP。User Story 2P2管理历史与收藏查询历史、收藏、快捷重查等能力继续可用且遵循统一的可见性与授权规则避免页面能看见但接口不允许或接口暴露不该看到的数据。User Story 3P3加载实例与表元数据实例列表、database 列表和 table 列表通过统一接口提供支撑页面选择器的正常联动。1.2 范围收口与质量清单在进入规划前规格经过了一轮质量检查requirements.md 记录了三个维度的验收结论Content Quality规格不含实现细节语言、框架、API聚焦用户价值与业务需求面向非技术干系人可读所有必填章节完成。Requirement Completeness无遗留[NEEDS CLARIFICATION]标记需求可测试、无歧义成功标准可量化且与实现无关验收场景完整边界情况已识别范围界定清晰依赖与假设已列出。Feature Readiness全部功能需求有明确验收标准用户场景覆盖主流程成功标准可量化规格中没有混入实现细节。关键收口结论原文 Note 部分按用户最新确认的6 个接口完成范围收敛——实例列表、database 列表、table 列表、执行查询、历史查询记录、收藏 SQL同时明确表结构查看、AI 生成 SQL、导出工单、查询权限申请不在本次迁移范围之内。1.3 功能需求清单FR规格定义了 12 条功能需求构成迁移的验收基准编号需求要点FR-001将 6 个后端交互能力迁移到统一接口层FR-002统一遵循现有集中式授权配置认证、权限校验、资源范围控制表现一致FR-003现有页面无需新增学习成本即可完成实例选择、语句提交、结果查看FR-004查询执行保留服务端安全控制实例校验、语句合法性校验、查询权限校验、行数限制、超时终止、脱敏、审计留痕FR-005历史查询接口支持分页、筛选、关键字搜索按角色限制可见范围FR-006收藏/取消收藏/别名维护仅允许作用于有权访问的记录FR-007~FR-009可访问实例列表、database 列表、table 列表读取能力与资源范围校验FR-010迁移后各接口返回稳定、一致、可预期的成功/失败响应FR-011建立清晰的接口清单与迁移边界发布时无遗漏旧入口依赖FR-012审计角色、普通用户、超级用户保持既有数据访问差异对应的可量化成功标准SC-001~SC-004包括页面全部后端依赖完成迁移映射并 100% 覆盖授权用户主流程步骤数不高于当前、95% 以上样例一次完成越权访问 100% 被统一授权策略拒绝既有回归场景 95% 以上保持原业务结果。二、接口清单与迁移边界2.1 规范化 DRF Endpoint5 个按 plan.md 与 quickstart.md迁移后形成 5 个规范化 DRF 端点GET /api/v1/sqlquery/instances/—— 当前用户可访问实例列表GET /api/v1/sqlquery/resources/—— 单实例下的 database 或 table 资源POST /api/v1/sqlquery/execute/—— 执行一次 SQL 查询GET /api/v1/sqlquery/logs/—— 历史查询记录bootstrap-table 分页结构POST /api/v1/sqlquery/favorites/—— 收藏/取消收藏实际源码中还在sql_api/urls.py注册了一个配套端点POST /api/v1/sqlquery/describetable/表结构查看以及sql_api/api_sqlquery.py中对应的SQLQueryDescribeTableView。需要注意的是表结构查看在规格 Note 中被明确排除在本次 6 接口范围之外其代码是作为相邻能力保留的辅助端点api_sqlquery.py。2.2 Legacy 兼容别名为保证页面不因迁移而中断OpenAPI 契约 中声明了 5 组旧路径到新接口的映射关系Legacy 路径新路径/group/user_all_instances//api/v1/sqlquery/instances//instance/instance_resource//api/v1/sqlquery/resources//query//api/v1/sqlquery/execute//query/querylog//api/v1/sqlquery/logs//query/favorite//api/v1/sqlquery/favorites/从当前仓库实现看前端模板 sqlquery.html 中的实际 AJAX 调用已直接指向规范化路径如 297 行/api/v1/sqlquery/logs/、1111 行/api/v1/sqlquery/execute/、1327 行/api/v1/sqlquery/resources/、1603 行/api/v1/sqlquery/instances/、447/477 行/api/v1/sqlquery/favorites/即后端收敛 前端渐进切换的双轨策略已落地legacy 层由 sql/query.py 等函数视图复用同一服务层execute_sql_query、list_query_logs、update_favorite保持旧入口可用。2.3 关键决策迁移缝与 URL 策略research.md 中记录了核心架构决策Decision 1迁移缝Migration seamDRF 视图 共享后端服务抽取把重构集中在后端避免把复杂逻辑继续留在 template AJAX 对应的函数视图中。URL 策略提供规范化/api/v1/sqlquery/...路径同时保留旧 URL 兼容别名兼顾长期可维护性与尽量不改前端。被拒绝的方案仅新增新 URL 并强制前端全部切换改动面过大把旧函数视图直接改成 DRF 逻辑但不建规范化 namespace长期可发现性差。三、权限模型为页面场景显式收敛3.1 默认 API 权限为什么不能直接沿用Archery 的全局 DRF 配置在 archery/settings.py 中REST_FRAMEWORK { DEFAULT_SCHEMA_CLASS: drf_spectacular.openapi.AutoSchema, DEFAULT_RENDERER_CLASSES: (rest_framework.renderers.JSONRenderer,), DEFAULT_AUTHENTICATION_CLASSES: ( rest_framework_simplejwt.authentication.JWTAuthentication, rest_framework.authentication.SessionAuthentication, ), DEFAULT_PERMISSION_CLASSES: (sql_api.permissions.IsApiSystemAdmin,), DEFAULT_THROTTLE_RATES: {anon: 120/min, user: 600/min}, DEFAULT_FILTER_BACKENDS: (django_filters.rest_framework.DjangoFilterBackend,), DEFAULT_PAGINATION_CLASS: rest_framework.pagination.PageNumberPagination, PAGE_SIZE: 5, }其中IsApiSystemAdminpermissions.py只放行已登录且为超级管理员的用户而IsInUserWhitelistpermissions.py要求用户 ID 出现在SysConfig的api_user_whitelist配置中。这两者面向开放 API都不适用于模板页面中的普通登录用户——如果 SQLQuery 视图直接继承默认权限页面绝大多数 AJAX 请求会被拒绝。3.2 页面场景的权限策略research.mdDecision 2确定的方案是页面场景的 DRF 视图显式使用SessionAuthentication/IsAuthenticated与 endpoint-specific 的 Django permission/resource 校验不沿用默认白名单同时不采用把所有页面用户加入api_user_whitelist会把页面授权语义错误耦合到开放 API 白名单也不采用彻底绕过 DRF permission 只在 service 层做权限认证与权限边界不清晰。落地到 api_sqlquery.py 中每个视图都声明permission_classes [permissions.IsAuthenticated]再按接口语义做 endpoint-specific 校验执行查询SQLQueryExecuteViewapi_sqlquery.py要求user.is_superuser或user.has_perm(sql.query_submit)否则返回{status: 1, msg: 无执行查询权限, data: {}}。历史记录SQLQueryLogsViewapi_sqlquery.py要求超级用户、sql.menu_sqlquery或sql.audit_user权限之一否则返回空列表{total: 0, rows: []}不暴露任何历史数据。收藏操作SQLQueryFavoritesViewapi_sqlquery.py要求超级用户或sql.menu_sqlquery权限否则返回{status: 1, msg: 无收藏操作权限}。可见登录 页面权限 资源级 service 校验三层结构与旧函数视图的permission_required装饰器语义如 sql/query.py 的sql.query_submit、sql/query.py 的sql.menu_sqlquery/sql.audit_user一一对应实现了充分利用 DRF 授权配置且不改变角色语义。四、数据模型与请求/响应契约4.1 核心实体定义data-model.md 定义了 7 个关键实体全部在 serializers.py 与 OpenAPI 契约 中落地实体关键字段说明AccessibleInstanceItemid、type、db_type、instance_name用户可访问实例摘要按user_instances()过滤保持实例名 locale-aware 排序InstanceResourceRequestinstance_name/instance_id、resource_typedatabase/table、可选db_name/schema_name资源联动请求resource_typetable时必须提供db_nameSqlQueryExecutionRequestinstance_name、db_name、sql_content、limit_num可选schema_name/tb_name执行查询输入运行期派生request_user、priv_check_result、effective_limit_num、超时终止用的schedule_name/thread_idSqlQueryExecutionResultstatus/msg/data嵌套column_list、rows、query_time、mask_time、full_sql、seconds_behind_master、error页面可解析的执行结果 envelopeQueryLogListRequestlimit、offset、search、star、query_log_idbootstrap-table 历史列表请求QueryLogItemid、instance_name、db_name、sqllog、effect_row、cost_time、user_display、favorite、alias、create_time历史单行记录字段名与QueryLog模型及表格列配置一致FavoriteMutationRequestquery_log_id、starbool/string、alias可选收藏/取消收藏动作4.2 Serializer 的校验规则源码佐证实例列表SqlQueryInstancesQuerySerializertype可选、db_type与tag_codes为ListField视图通过_get_list_values()api_sqlquery.py兼容db_typemysqldb_typemssql与db_type[]mysql两种传参风格。资源列表SqlQueryResourceQuerySerializerresource_type支持database/schema/table/column/server_info五种取值instance_id或instance_name必须提供其一table/schema要求db_name非空column要求db_name与tb_name均非空。执行查询SqlQueryExecuteSerializerinstance_name、db_name、sql_content必填limit_num为min_value0的整型默认 0。历史列表SqlQueryLogsQuerySerializerlimit/offset默认 0star经validate_star将字符串true大小写不敏感归一化为布尔值。收藏SqlQueryFavoriteSerializerquery_log_id最小值为 1star同样归一化为布尔alias默认为空字符串。4.3 响应契约按 Endpoint 保留不做全局统一research.mdDecision 3特别强调响应兼容是按 endpoint 保留而不是全局统一。因为查询页面中不同 AJAX 回调依赖不同结构执行查询与收藏{status, msg, data}/{status, msg}历史记录{total, rows}bootstrap-table 直接依赖实例/资源列表{status, msg, data}data 为扁平数组被否决的方案包括统一为 DRF 默认{detail: ...}或分页count/results前端需大范围改写强制全接口统一status/msg/data会破坏 bootstrap-table 历史列表。为兼容特殊 JSON 类型SimpleJSONRendererrenderers.py重写了渲染器对 bytes 尝试 UTF-8 解码、失败则 base64 编码并复用ExtendJSONEncoder.convert处理 Decimal、datetime 等引擎返回类型同时开启int_as_string_bitcount53防止大整数精度丢失——这是查询结果中的大整数、Decimal、日期时间必须对现有 JS 消费者保持 JSON 安全这一兼容规则见>GET /api/v1/sqlquery/instances/?tag_codescan_read获取某实例的 database 列表GET /api/v1/sqlquery/resources/?instance_nametest-mysqlresource_typedatabase获取某实例某 database 的 table 列表GET /api/v1/sqlquery/resources/?instance_nametest-mysqldb_namearcheryresource_typetable执行查询POST /api/v1/sqlquery/execute/ { instance_name: test-mysql, db_name: archery, schema_name: , tb_name: sql_workflow, sql_content: select 1;, limit_num: 100 }历史记录分页 关键字搜索GET /api/v1/sqlquery/logs/?limit20offset0searchselect收藏一条历史记录并设置别名POST /api/v1/sqlquery/favorites/ { query_log_id: 123, star: true, alias: 常用检查语句 }十、测试策略pytest-first 与共享夹具10.1 测试约束TSC规格 spec.md 中的 Test Strategy Constraints 定义了四条硬性约束TSC-001验证优先覆盖接口授权、资源范围控制、查询保护、历史可见性和响应契约的 pytest 单元测试。TSC-002共享测试准备通过conftest.py或可复用夹具统一管理禁止为每个接口重复构建用户、实例、权限和查询日志数据。TSC-003集成测试仅用于证明跨越认证、权限、视图与查询引擎边界的关键行为如统一授权是否真正生效。TSC-004任何新增集成测试必须附带简短说明解释为何无法仅靠单元测试证明。10.2 落地的测试资产共享夹具集中在仓库根目录 conftest.pynormal_user普通用户、super_user超级用户、db_instance实例、resource_group、instance_tag、setup_sys_config等供sql_api与sql/tests.py复用满足 TSC-002。聚焦单元/集成测试sql_api/test_sqlquery_api.py 覆盖实例列表返回结构、资源列表返回结构、表结构、执行查询权限门槛无sql.query_submit权限返回status1、执行服务调用、非 UTF-8 bytes 经SimpleJSONRenderer序列化的兼容性bytes 被 base64 编码、历史列表total/rows结构、收藏返回结构并通过monkeypatch替换服务函数实现 unit-first。legacy 回归sql/tests.py 中test_query_log验证GET /api/v1/sqlquery/logs/的 star 过滤与total统计test_star/test_un_star验证收藏与取消收藏对QueryLog.favorite、alias的实际落库效果sql/test_query.py则对 legacy 视图_querylog、favorite的参数转换与服务调用做纯单元验证。服务层测试sql/test_services.py 覆盖list_instance_resources的无权限实例、database 成功、非法 resource_type、server_info 兜底等分支。聚焦测试命令取自 quickstart.mdpytest -q sql_api/test_sqlquery_api.py pytest -q sql/tests.py -k sqlquery or query_log or star10.3 单元测试优先的原因research.mdDecision 7指出端到端前端联动测试过重、与后端集中改造不匹配仅保留旧sql/tests.pysmoke 又无法证明 DRF 权限与契约的稳定性。因此集成测试只覆盖三类边界DRF auth wiring、legacy alias 路由绑定、SessionAuthentication 登录场景tasks.md T014/T021 已标记完成其余执行路径一律通过 fake engine / monkeypatch 的 unit-first 方式验证。十一、边界情况与假设11.1 规格明确的边界情况spec.md Edge Cases用户打开页面后权限发生变化再次请求任一接口时必须按最新权限立即拒绝无权操作。查询执行成功但脱敏失败或超时控制触发时必须返回一致的失败或降级结果不得出现前端无法识别的异常格式sqlquery_service中按照配置放行分支即为此设计。切换不同数据库类型时实例/database/table 加载结果必须对应当前选择不能沿用上一种数据库的上下文。目标实例不存在、database 不存在或范围内无 table 时给出清晰反馈而非不一致数据。审计角色、普通用户、超级用户访问历史时只暴露各自允许范围内的数据list_query_logs的username过滤已实现。11.2 假设与排除范围spec.md Assumptions仅覆盖明确收口的 6 个接口页面保留现有入口与交互只做迁移所需的最小前端适配。现有查询引擎、脱敏逻辑、权限规则、审计记录、AI 生成能力继续复用本次不重新设计业务规则。统一授权配置已在现有 API 体系中可用本次目标是让 SQLQuery 接口接入并遵循而非新增独立授权模型。表结构查看、AI 生成 SQL、线下导出工单、查询权限申请不在核心迁移范围虽然describetable端点已作为相邻能力落地。十二、参考文件速查规格与计划spec.md、plan.md、research.md、data-model.md、quickstart.md、tasks.md、requirements.md、OpenAPI 契约接口实现api_sqlquery.py、serializers.py、permissions.py、renderers.py、urls.py服务层sqlquery_service.py、querylog_service.py、resource_service.py兼容层与业务query.py、instance.py、resource_group.py、query_privileges.py、models.py、sqlquery.html测试test_sqlquery_api.py、conftest.py、tests.py、test_services.py赞分享后端数据库【免费下载链接】ArcherySQL 审核查询平台项目地址https://gitcode.com/gh_mirrors/ar/Archery点击查看免费下载相关推荐Archery SQLQuery 接口 DRF 统一迁移实战指南接口清单、兼容别名与验证流程Archery SQLQuery 接口 DRF 统一迁移实战指南接口清单、兼容别名与验证流程 导读 本文围绕 Archery 中 002 migrate sq后端数据库Archery SQLQuery 接口统一化基于 Django REST Framework 的 SQL 查询平台接口重构实战指南Archery SQLQuery 接口统一化基于 Django REST Framework 的 SQL 查询平台接口重构实战指南 导读 本文围绕 Arche后端数据库AGT v4 策略语言移除从兼容桥接走向 ACS 单一策略契约的迁移全指南AGT v4 策略语言移除从兼容桥接走向 ACS 单一策略契约的迁移全指南 导读 本文基于 agent governance toolkitAGT的审计记人工智能AI AgentAI 安全治理策略引擎认证鉴权Agent 沙箱可观测性上一篇Synology HDD db 教程3步把第三方硬盘加入群晖兼容数据库下一篇免费开源视频下载神器VideoDownloadHelper终极使用指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表