# SQLor 技术文档 `SQLor` 是一个用于简化数据库操作的异步 Python 数据库访问类,支持参数化 SQL 执行、分页查询、CRUD 操作(Create, Read, Update, Delete)、元数据获取、动态 SQL 构建等功能。它设计为可扩展,适用于多种数据库后端。 --- ## 目录 1. [概述](#概述) 2. [依赖与环境要求](#依赖与环境要求) 3. [核心功能](#核心功能) 4. [主要类与方法说明](#主要类与方法说明) - [`db_type_2_py_type`](#db_type_2_py_type) - [`SQLorException`](#sqlorexception) - [`findNamedParameters`](#findnamedparameters) - [`uniParams`](#uniparams) - [`readsql`](#readsql) - [`SQLor` 类](#sqlor-类) - 初始化 - 元数据管理 - 连接与游标控制 - SQL 处理与转换 - 查询执行 - 分页与排序 - 聚合操作(Pivot) - 表结构信息获取 - DDL 与表定义操作 - CRUD 操作(C/U/R/D) 5. [使用示例](#使用示例) 6. [异常处理](#异常处理) 7. [配置说明](#配置说明) --- ## 概述 `SQLor` 提供了一个统一接口来执行 SQL 查询和命令,并通过命名参数 `${var}$` 支持模板化 SQL。其主要特点包括: - 异步/同步双模式支持。 - 参数自动替换与安全绑定。 - 自动识别 `SELECT`, `INSERT/UPDATE/DELETE`, `DDL` 类型并返回相应结果。 - 支持分页、排序、条件过滤。 - 内置对表结构(字段、主键、外键、索引)的元数据查询。 - 支持自定义函数注册钩子(before/after 钩子)。 - 可扩展的类型转换机制。 - 简化的 CRUD 接口(I/C/R/U/D)。 --- ## 依赖与环境要求 ### 第三方依赖 ```python from appPublic.myImport import myImport from appPublic.dictObject import DictObject from appPublic.unicoding import uDict from appPublic.myTE import MyTemplateEngine from appPublic.objectAction import ObjectAction from appPublic.argsConvert import ArgsConvert, ConditionConvert from appPublic.registerfunction import RegisterFunction from appPublic.log import info, exception, debug ``` > ⚠️ 注意:这些模块属于 `appPublic` 包,需确保已安装或项目中包含该包。 ### Python 内置模块 - `os` - `sys` - `decimal` - `datetime` - `codecs` - `re` - `json` - `traceback` ### 环境变量 ```python os.environ['NLS_LANG'] = 'SIMPLIFIED CHINESE_CHINA.UTF8' ``` > 仅在 Oracle 数据库环境下需要设置 NLS 编码以支持中文 UTF-8。 --- ## 核心功能 | 功能 | 描述 | |------|------| | 参数化 SQL | 使用 `${var}$` 占位符进行变量注入 | | 异步支持 | 支持 `async/await` 模式运行 SQL | | 分页查询 | 自动生成分页 SQL(需子类实现模型) | | 排序与过滤 | 支持动态排序字段和条件表达式 | | 元数据提取 | 获取表、字段、主键、索引等结构信息 | | CRUD 封装 | 提供 `C()`(创建), `R()`(读取), `U()`(更新), `D()`(删除) 方法 | | 回调机制 | 支持逐行处理查询结果 | | 类型转换 | 自动将数据库类型转为 Python 原生类型 | --- #### `tables()` 返回数据库中所有表的列表。 #### `indexes(tablename)` 返回某表的所有索引信息(需子类实现 `indexesSQL()`) #### `fields(tablename)` 返回字段列表,包含名称、类型(映射后),例如: ```python [ {"name": "id", "type": "int"}, {"name": "name", "type": "string"} ] ``` #### `primary(tablename)` 返回主键字段列表。 #### `fkeys(tablename)` 返回外键关系。 #### `getTableDesc(tablename)` 综合获取表的完整描述(summary + fields + indexes),并缓存至 `metadatas`。 --- ### DDL 与表操作 #### `createTable(tabledesc)` 使用模板引擎渲染建表语句并执行。 依赖 `self.ddl_template` 和 `MyTemplateEngine`。 --- ### 事务控制 #### `commit()` 提交事务,重置 `dataChanged=False` #### `rollback()` 回滚事务 --- ### CRUD 接口(I/C/R/U/D) 遵循 RESTful 风格简写: #### `I(tablename)` 等价于 `getTableDesc()` — 获取表结构定义。 #### `C(tablename, ns)` 插入新记录。 - 自动提取 `ns` 中存在于表字段的部分 - 触发 `before` / `after` 钩子函数 - 生成 INSERT 语句 #### `R(tablename, ns, filters=None)` 读取记录。 - 若传入 `page` 参数 → 返回分页 `{total, rows}` - 否则返回匹配行列表 - 支持简单等值条件或复杂 `DBFilter` #### `U(tablename, ns)` 更新记录。 - 使用主键做 WHERE 条件 - 更新非主键字段 - 支持钩子函数 #### `D(tablename, ns)` 删除记录。 - 使用主键匹配删除 - 支持钩子函数 --- ## 使用示例 ### 1. 初始化 SQLor 实例 ```python dbdesc = { 'dbname': 'mydb' } sqlor = SQLor(dbdesc=dbdesc) sqlor.setCursor(False, conn, cursor) # 同步模式 ``` ### 2. 执行参数化查询 ```python sql = "SELECT * FROM users WHERE age > ${min_age}$" result = [] await sqlor.execute(sql, {'min_age': 18}, lambda rec: result.append(rec)) ``` ### 3. 分页查询 ```python desc = { "sql_string": "SELECT id, name FROM users", "sortfield": "name" } ns = {"page": 1, "rows": 10} data = await sqlor.runSQLPaging(desc, ns) # → {"total": 100, "rows": [...]} ``` ### 4. CRUD 操作 ```python # 创建 await sqlor.C("users", {"name": "Alice", "age": 25}) # 读取(分页) res = await sqlor.R("users", {"page": 1, "rows": 10}) # 更新 await sqlor.U("users", {"id": 1, "age": 26}) # 删除 await sqlor.D("users", {"id": 1}) ``` ### 5. 获取表结构 ```python desc = await sqlor.I("users") print(desc['fields']) ``` --- ## 异常处理 所有 SQL 执行异常都会被捕获并记录日志: ```python exception(f"{markedSQL=},{datas=}, {e=}, {fe=}") raise e ``` 推荐外部捕获 `Exception` 或自定义 `SQLException`。 --- ## 配置说明 ### 占位符配置 | 符号 | 默认 | 用途 | |------|------|------| | `sqltp` / `sqlts` | `$[` / `]$` | 控制结构模板(如 IF) | | `sqlvp` / `sqlvs` | `${` / `}$` | 变量参数占位符 | 示例: ```sql SELECT * FROM t WHERE status = ${status}$ $[ IF active ]$ AND active = 1 $[ ENDIF ]$ ``` ### 分页模型扩展 子类应重写 `pagingSQLmodel()` 提供数据库特定的分页语法。 例如 MySQL 子类: ```python def pagingSQLmodel(self): return "SELECT * FROM (%s) t LIMIT ${rows}$ OFFSET ${from_line}$" ``` Oracle 示例: ```python def pagingSQLmodel(self): return """ SELECT * FROM ( SELECT a.*, ROWNUM rn FROM ( %s ORDER BY ${sort}$ ) a WHERE ROWNUM <= ${end_line}$ ) WHERE rn > ${from_line}$ """ ``` --- ## 总结 `SQLor` 是一个轻量级但功能完整的数据库抽象层,适合用于 Web API 后端、ETL 工具或管理后台的数据访问组件。其优势在于: ✅ 清晰的 CRUD 接口 ✅ 支持异步高性能场景 ✅ 安全的参数绑定 ✅ 易于扩展不同数据库方言 > ⚠️ **待改进点**: - 修复 `SQLException.__init__` 错误 - `commit()` 中 `self.datachanged` 应为 `self.dataChanged` - `pagingdata()` 中 `cnt_desc` 未定义 - `setMeta` 中 `getMeta(self.tablename)` 应为 `self.getMeta(...)` --- 📝 **版本**: v1.0 📅 **最后更新**: 2025-04-05 👨‍💻 **作者**: Auto-generated Documentation Tool