This commit is contained in:
yumoqing 2025-11-07 16:47:22 +08:00
parent d3c9c060ea
commit b815d7e701

View File

@ -34,7 +34,7 @@
## 概述
`SQLor` 提供了一个统一接口来执行 SQL 查询和命令,并通过命名参数 `${var}` 支持模板化 SQL。其主要特点包括
`SQLor` 提供了一个统一接口来执行 SQL 查询和命令,并通过命名参数 `${var}$` 支持模板化 SQL。其主要特点包括
- 异步/同步双模式支持。
- 参数自动替换与安全绑定。
@ -89,7 +89,7 @@ os.environ['NLS_LANG'] = 'SIMPLIFIED CHINESE_CHINA.UTF8'
| 功能 | 描述 |
|------|------|
| 参数化 SQL | 使用 `${var}` 占位符进行变量注入 |
| 参数化 SQL | 使用 `${var}$` 占位符进行变量注入 |
| 异步支持 | 支持 `async/await` 模式运行 SQL |
| 分页查询 | 自动生成分页 SQL需子类实现模型 |
| 排序与过滤 | 支持动态排序字段和条件表达式 |
@ -100,289 +100,6 @@ os.environ['NLS_LANG'] = 'SIMPLIFIED CHINESE_CHINA.UTF8'
---
## 主要类与方法说明
### `db_type_2_py_type(o)`
将特定数据库类型转换为 Python 原生类型。
#### 参数
- `o`: 数据库字段值
#### 返回值
| 输入类型 | 输出 |
|--------|-------|
| `decimal.Decimal` | `float` |
| `datetime.datetime` | 字符串格式 `'YYYY-MM-DD HH:MM:SS'` |
| `datetime.date` | `'YYYY-MM-DD'` |
| 其他 | 原值 |
#### 示例
```python
db_type_2_py_type(decimal.Decimal('3.14')) → 3.14
```
---
### `SQLorException`
自定义异常类,封装 SQL 执行错误。
> ❗ 当前代码存在拼写错误:`__int__` 应为 `__init__`,且 `supper` 应为 `super`
#### 属性
- `response`: `"error"`
- `errtype`: `"SQLor"`
- `errmsg`: 异常消息字符串
#### 示例输出
```
errtype:SQLor,errmsg=database error...
```
> ✅ **建议修复**
```python
class SQLException(Exception):
def __init__(self, **kvs):
super(SQLException, self).__init__(**kvs)
self.dic = {
'response': 'error',
'errtype': 'SQLor',
'errmsg': str(self)
}
def __str__(self):
return 'errtype:%s,errmsg=%s' % (self.dic['errtype'], self.dic['errmsg'])
```
---
### `setValues(params, ns)`
从命名空间 `ns` 或系统环境变量中查找参数值。
#### 参数
- `params`: 参数名(字符串)
- `ns`: 命名空间字典
#### 返回
优先从 `ns` 中取值,若无则尝试 `os.getenv(params)`
---
### `findNamedParameters(sql)`
解析 SQL 字符串中的所有 `${...}` 形式的命名参数。
#### 示例
```python
sql = "SELECT * FROM user WHERE id = ${uid}$ AND name = ${uname}$"
findNamedParameters(sql)
# 返回 ['${uid}$', '${uname}$']
```
---
### `uniParams(params1)`
去重保留唯一参数名列表。
#### 示例
```python
uniParams(['${a}$', '${b}$', '${a}$']) → ['${a}$', '${b}$']
```
---
### `readsql(fn)`
读取指定文件路径的 SQL 文件内容UTF-8 编码)。
#### 参数
- `fn`: 文件路径
#### 返回
文件内容字符串。
---
## `SQLor`
### 初始化 `__init__`
#### 参数
| 参数 | 默认值 | 说明 |
|------|--------|------|
| `dbdesc` | None | 数据库描述字典,至少含 `dbname` |
| `sqltp`, `sqlts` | `$[`, `]$` | 模板占位符开始/结束符号 |
| `sqlvp`, `sqlvs` | `${`, `}$` | 变量占位符开始/结束符号 |
#### 初始化行为
- 设置连接状态(`conn`, `cur`
- 初始化元数据缓存 `metadatas`
- 创建 `ConditionConvert` 实例用于条件表达式处理
---
### 元数据管理
#### `setMeta(tablename, meta)`
保存表的元数据到内存缓存。
#### `getMeta(tablename)`
获取指定表的缓存元数据。
#### `removeMeta(tablename)`
清除指定表的元数据缓存。
---
### 连接与游标控制
#### `setCursor(async_mode, conn, cur)`
绑定数据库连接和游标对象。
#### `getConn()`
返回当前数据库连接对象。
#### `cursor()`
返回当前游标对象。
---
### 类型转换支持
#### `setConvertFunction(typ, func)`
注册用户自定义类型转换函数。
#### `convert(typ, value)`
调用注册的转换函数处理值。
---
### SQL 类型判断
#### `getSqlType(sql)`
判断 SQL 语句类型。
| 类型 | 条件 |
|------|------|
| `"qry"` | 以 `SELECT` 开头 |
| `"dml"` | `INSERT`, `UPDATE`, `DELETE` |
| `"ddl"` | 其他(如 `CREATE`, `DROP` |
---
### SQL 模板处理
#### `maskingSQL(org_sql, NS)`
将命名参数 `${var}$` 替换为 `?` 并生成参数列表。
##### 步骤
1. 先替换 `$[...]$` 模板片段(如条件块)
2. 提取 `${var}$` 参数名
3. 替换为 `?` 占位符
4. 返回 `(标记后的SQL, 参数值列表)`
##### 特殊变量
- `__mainsql__`: 不参与参数绑定,用于嵌套 SQL 注入
---
### 执行方法
#### `execute(sql, value, callback, **kwargs)`
执行单条 SQL支持回调逐行处理结果。
##### 流程
- 调用 `runVarSQL` 执行 SQL
- 若是查询 (`qry`) 且有回调,则逐行调用 `callback(DictObject(row))`
- 若是 DML标记 `dataChanged=True`
#### `executemany(sql, values)`
批量执行 SQL适用于 `INSERT` 等)
---
### 分页与排序
#### `sortSQL(sql, NS)`
添加 `ORDER BY` 子句。
- 支持 `NS['sort']` 为字符串或列表
#### `pagingSQL(sql, paging, NS)`
构建分页 SQL需配合 `pagingSQLmodel()` 使用。
> 默认为空,需由子类重写提供具体数据库分页语法(如 MySQL 的 `LIMIT OFFSET` 或 Oracle 的 `ROWNUM`
##### 参数
- `pagename`: 页码参数名(默认 `'page'`
- `rowsname`: 每页行数(默认 `'rows'`
- `sortname`: 排序字段(可选)
##### 示例 NS
```python
{
'page': 2,
'rows': 20,
'sort': 'id desc'
}
```
#### `recordCnt(sql)`
包装 SQL 查询总记录数:
```sql
SELECT COUNT(*) rcnt FROM (your_sql) rowcount_table
```
---
### 过滤器支持
#### `filterSQL(sql, filters, NS)`
将一组条件过滤器合并进原 SQL。
每个 filter 是一个带 `${}` 的模板字符串,若其中变量未在 `NS` 中存在,则忽略此条件(替换为 `1=1`)。
最终生成:
```sql
SELECT * FROM (original_sql) filter_table WHERE f1 AND f2 ...
```
---
### Pivot 表格转换
#### `pivotSQL(tablename, rowFields, columnFields, valueFields)`
生成透视表 SQL。
##### 逻辑
1. 查询 `columnFields` 的所有唯一值作为列头
2. 使用 `CASE WHEN` 构造每列聚合
3. 使用 `SUM` 聚合数值字段
##### 示例输出
```sql
SELECT dept,
SUM(salary_0) salary_0, -- 北京
SUM(salary_1) salary_1 -- 上海
FROM (
SELECT dept,
CASE WHEN city='北京' THEN salary ELSE 0 END AS salary_0,
CASE WHEN city='上海' THEN salary ELSE 0 END AS salary_1
FROM employees
) GROUP BY dept;
```
#### `pivot(desc, ...)`
执行 pivot 查询并返回结果列表。
---
### 元数据查询方法
#### `tables()`
返回数据库中所有表的列表。