Metadata-Version: 2.4
Name: kdocs-sql-model
Version: 1.0.0
Summary: A sqlite3-like Python interface for KDocsSQL database operations
Author-email: xiaomayisjh <xiaomayisjh@outlook.com>
License-Expression: GPL-3.0-or-later
Project-URL: Homepage, https://github.com/xiaomayisjh/KDocsSQL
Project-URL: Documentation, https://github.com/xiaomayisjh/KDocsSQL#readme
Project-URL: Repository, https://github.com/xiaomayisjh/KDocsSQL.git
Project-URL: Issues, https://github.com/xiaomayisjh/KDocsSQL/issues
Keywords: kdocs,wps,sql,database,sqlite3,airscript,金山文档
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Database
Classifier: Topic :: Database :: Front-Ends
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.7
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.20.0
Provides-Extra: dev
Requires-Dist: pytest>=6.0; extra == "dev"
Requires-Dist: black>=22.0; extra == "dev"
Requires-Dist: flake8>=4.0; extra == "dev"
Requires-Dist: mypy>=0.900; extra == "dev"
Dynamic: license-file

# KDocsSQL Model 使用文档

类似 sqlite3 的 KDocsSQL 数据库操作接口，提供简洁直观的 Python API。

---

## 目录

- [简介](#简介)
- [安装与配置](#安装与配置)
  - [依赖](#依赖)
  - [环境变量配置](#环境变量配置)
  - [文件结构](#文件结构)
- [快速开始](#快速开始)
- [API 参考](#api-参考)
  - [模块函数](#模块函数)
  - [Connection 类](#connection-类)
  - [Cursor 类](#cursor-类)
  - [异常类](#异常类)
- [使用示例](#使用示例)
  - [基本用法](#基本用法)
  - [参数化查询](#参数化查询)
  - [批量操作](#批量操作)
  - [上下文管理器](#上下文管理器)
  - [字典格式获取](#字典格式获取)
  - [DDL 操作](#ddl-操作)
  - [便捷方法](#便捷方法)
- [与 sqlite3 的对比](#与-sqlite3-的对比)
- [最佳实践](#最佳实践)
- [常见问题](#常见问题)

---

## 简介

`kdocs_sql_model` 是一个为 KDocsSQL 数据库设计的 Python 模块，提供与标准库 `sqlite3` 兼容的 API 接口。这使得开发者可以：

- **零学习成本**：如果你熟悉 sqlite3，就能立即上手
- **类型安全**：完整的类型注解支持
- **Pythonic**：支持上下文管理器、迭代器等 Python 特性
- **功能丰富**：支持参数化查询、批量操作、字典格式获取等

### 主要特性

| 特性 | 说明 |
|------|------|
| 连接管理 | 支持上下文管理器自动关闭连接 |
| 游标操作 | 完整的游标功能，支持迭代 |
| 参数化查询 | 使用 `?` 占位符，防止 SQL 注入 |
| 批量操作 | `executemany` 批量执行 SQL |
| 字典获取 | `fetchone_dict` / `fetchall_dict` |
| 异常处理 | 完整的异常层次结构 |
| 便捷方法 | select/insert/update/delete 等快捷操作 |

---

## 安装与配置

### 从 PyPI 安装（推荐）

```bash
pip install kdocs-sql-model
```

### 从源码安装

```bash
git clone https://github.com/xiaomayisjh/KDocsSQL.git
cd KDocsSQL/kdocs_sql_model
pip install -e .
```

### 依赖

```bash
pip install requests
```

### 环境变量配置

本模块使用环境变量进行认证配置，请勿在代码中硬编码敏感信息。

**方式一：设置环境变量（推荐）**

Linux/macOS:
```bash
export KDOCS_API_TOKEN='your_api_token_here'
export KDOCS_WEBHOOK_URL='your_webhook_url_here'
```

Windows PowerShell:
```powershell
$env:KDOCS_API_TOKEN='your_api_token_here'
$env:KDOCS_WEBHOOK_URL='your_webhook_url_here'
```

Windows CMD:
```cmd
set KDOCS_API_TOKEN=your_api_token_here
set KDOCS_WEBHOOK_URL=your_webhook_url_here
```

**方式二：使用 .env 文件**

1. 复制项目根目录下的 `.env.example` 为 `.env`
2. 填入您的实际配置值

```bash
cp .env.example .env
```

`.env` 文件内容示例：
```
KDOCS_API_TOKEN=your_api_token_here
KDOCS_WEBHOOK_URL=https://www.kdocs.cn/api/v3/ide/file/YOUR_FILE_ID/script/YOUR_SCRIPT_ID/sync_task
```

**获取认证信息：**

1. **API Token**: 金山文档 → 空间设置 → 开发者选项 → AirScript Token
2. **Webhook URL**: 在 AirScript 脚本编辑器中创建 Webhook 后获取

### 文件结构

```
kdocs_sql_model/
├── __init__.py              # 模块初始化
├── kdocs_sql_model.py       # 主模块
├── test_kdocs_sql_model.py  # 测试脚本
└── README.md                # 本文档
```

### 导入模块

```python
import kdocs_sql_model as ksql

# 或者
from kdocs_sql_model import connect, Connection, Cursor
```

---

## 快速开始

### 1. 创建连接

```python
import kdocs_sql_model as ksql

# 创建连接
conn = ksql.connect(
    api_token="your_api_token",
    webhook_url="your_webhook_url"
)

# 使用完毕后关闭
conn.close()
```

### 2. 执行查询

```python
# 创建游标
cursor = conn.cursor()

# 执行 SQL
cursor.execute("SELECT * FROM Sheet1")

# 获取结果
for row in cursor:
    print(row)
```

### 3. 使用上下文管理器（推荐）

```python
with ksql.connect(api_token, webhook_url) as conn:
    for row in conn.execute("SELECT * FROM Sheet1"):
        print(row)
# 自动关闭连接
```

---

## API 参考

### 模块函数

#### `connect(api_token, webhook_url, timeout=30)`

创建数据库连接。

**参数：**

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| api_token | str | 是 | AirScript API Token |
| webhook_url | str | 是 | Webhook URL |
| timeout | int | 否 | 请求超时时间(秒)，默认 30 |

**返回：** `Connection` 对象

**示例：**

```python
conn = ksql.connect("your_token", "your_url", timeout=60)
```

---

#### `complete_statement(sql)`

检查 SQL 语句是否完整。

**参数：**

| 参数 | 类型 | 说明 |
|------|------|------|
| sql | str | SQL 语句 |

**返回：** `bool`

**示例：**

```python
ksql.complete_statement("SELECT * FROM t")  # True
ksql.complete_statement("")  # False
```

---

### 模块常量

```python
apilevel = "2.0"       # DB-API 级别
threadsafety = 1       # 线程安全级别（1 = 连接可跨线程共享，但游标不可）
paramstyle = "qmark"   # 参数风格（问号占位符）
```

---

### Connection 类

数据库连接类，管理与 KDocsSQL 的连接。

#### 属性

| 属性 | 类型 | 说明 |
|------|------|------|
| closed | bool | 连接是否已关闭 |
| row_factory | None | 行工厂（暂不支持） |
| text_factory | type | 文本工厂，默认 str |

#### 方法

##### `cursor()`

创建游标对象。

```python
cursor = conn.cursor()
```

---

##### `execute(sql, parameters=None)`

直接执行 SQL 语句（内部创建游标）。

```python
cursor = conn.execute("SELECT * FROM Sheet1 WHERE id = ?", (1,))
```

---

##### `executemany(sql, seq_of_parameters)`

批量执行 SQL 语句。

```python
conn.executemany(
    "INSERT INTO users (id, name) VALUES (?, ?)",
    [('1', '张三'), ('2', '李四')]
)
```

---

##### `executescript(sql_script)`

执行多条 SQL 语句（以分号分隔）。

```python
conn.executescript("""
    CREATE TABLE users (id, name);
    INSERT INTO users (id, name) VALUES ('1', '张三');
""")
```

---

##### `close()`

关闭连接。

```python
conn.close()
```

---

##### `commit()` / `rollback()`

提交/回滚事务。**注意：KDocsSQL 不支持事务，这两个方法为空操作。**

```python
conn.commit()    # 空操作
conn.rollback()  # 空操作
```

---

##### `tables()`

获取所有表名。**注意：KDocsSQL 不支持此功能，返回空列表。**

```python
tables = conn.tables()  # 返回 []
```

---

##### `columns(table)`

获取表的列名。

```python
cursor = conn.execute("SELECT * FROM Sheet1")
columns = [col[0] for col in cursor.description]
```

---

#### 便捷方法

Connection 类提供了以下便捷方法，简化常见操作：

##### `select(table, columns='*', where=None, order_by=None, limit=None, offset=None)`

执行 SELECT 查询。

```python
cursor = conn.select("users", ["id", "name"], where="age > '25'", limit=10)
```

---

##### `insert(table, data)`

执行 INSERT 插入。`data` 可以是字典（单行）或列表（多行）。

```python
conn.insert("users", {"id": "1", "name": "张三"})
conn.insert("users", [{"id": "1"}, {"id": "2"}])
```

---

##### `update(table, data, where)`

执行 UPDATE 更新。**必须指定 WHERE 条件。**

```python
conn.update("users", {"status": "inactive"}, "id = '1'")
```

---

##### `delete(table, where)`

执行 DELETE 删除。**必须指定 WHERE 条件。**

```python
conn.delete("users", "id = '1'")
```

---

##### `create_table(table, columns, if_not_exists=False)`

创建表。

```python
conn.create_table("users", ["id", "name", "age"], if_not_exists=True)
```

---

##### `drop_table(table, if_exists=False)`

删除表。

```python
conn.drop_table("users", if_exists=True)
```

---

##### `truncate_table(table)`

清空表数据。

```python
conn.truncate_table("users")
```

---

##### `add_column(table, column)` / `drop_column(table, column)`

添加/删除列。

```python
conn.add_column("users", "email")
conn.drop_column("users", "temp")
```

---

##### `rename_column(table, old_name, new_name)`

重命名列。

```python
conn.rename_column("users", "name", "username")
```

---

##### `rename_table(old_name, new_name)`

重命名表。

```python
conn.rename_table("users", "members")
```

---

##### `count(table, where=None)` / `sum(table, column, where=None)` / `avg(table, column, where=None)` / `max(table, column, where=None)` / `min(table, column, where=None)`

聚合函数便捷方法。

```python
total = conn.count("users")
avg_age = conn.avg("users", "age")
max_score = conn.max("users", "score", "status = 'active'")
```

---

### Cursor 类

数据库游标类，用于执行 SQL 语句并获取结果。

#### 属性

| 属性 | 类型 | 说明 |
|------|------|------|
| description | tuple | 结果列描述 `(name, type_code, ...)` |
| rowcount | int | 影响的行数 |
| lastrowid | int | 最后插入的行ID（始终为 None） |
| arraysize | int | `fetchmany()` 默认获取行数 |
| closed | bool | 游标是否已关闭 |

#### 方法

##### `execute(sql, parameters=None)`

执行 SQL 语句，返回自身支持链式调用。

```python
cursor.execute("SELECT * FROM users WHERE id = ?", (1,))
rows = cursor.fetchall()
```

---

##### `executemany(sql, seq_of_parameters)`

批量执行 SQL 语句。

```python
cursor.executemany(
    "INSERT INTO users (id, name) VALUES (?, ?)",
    [('1', '张三'), ('2', '李四'), ('3', '王五')]
)
print(f"插入了 {cursor.rowcount} 行")
```

---

##### `fetchone()`

获取下一行结果，返回元组或 None。

```python
row = cursor.fetchone()
if row:
    print(f"ID: {row[0]}, Name: {row[1]}")
```

---

##### `fetchmany(size=None)`

获取多行结果。

```python
rows = cursor.fetchmany(10)  # 获取 10 行
# 或使用 arraysize
cursor.arraysize = 5
rows = cursor.fetchmany()  # 获取 5 行
```

---

##### `fetchall()`

获取所有剩余结果。

```python
rows = cursor.fetchall()
for row in rows:
    print(row)
```

---

##### `fetchone_dict()`

获取下一行结果（字典格式）。

```python
row = cursor.fetchone_dict()
if row:
    print(f"ID: {row['id']}, Name: {row['name']}")
```

---

##### `fetchall_dict()`

获取所有剩余结果（字典格式）。

```python
rows = cursor.fetchall_dict()
for row in rows:
    print(f"ID: {row['id']}, Name: {row['name']}")
```

---

##### `scroll(value, mode='relative')`

滚动游标位置。

```python
# 相对滚动
cursor.scroll(2)  # 向前移动 2 行
cursor.scroll(-1)  # 向后移动 1 行

# 绝对定位
cursor.scroll(0, 'absolute')  # 移动到第 0 行
```

---

##### `close()`

关闭游标。

```python
cursor.close()
```

---

### 异常类

```
KDocsSQLError (基类)
├── OperationalError  # 操作错误（SQL语法错误、表不存在等）
├── DatabaseError     # 数据库错误
└── ProgrammingError  # 编程错误（游标已关闭等）
```

**使用示例：**

```python
try:
    cursor.execute("INVALID SQL")
except ksql.OperationalError as e:
    print(f"SQL 执行错误: {e}")
except ksql.KDocsSQLError as e:
    print(f"数据库错误: {e}")
```

---

## 使用示例

### 基本用法

```python
import kdocs_sql_model as ksql

# 创建连接
conn = ksql.connect(api_token, webhook_url)

# 创建表
conn.execute("""
    CREATE TABLE users (
        id,
        name,
        age,
        status
    )
""")

# 插入数据
conn.execute("""
    INSERT INTO users (id, name, age, status)
    VALUES ('1', '张三', '25', 'active')
""")

# 查询数据
cursor = conn.execute("SELECT * FROM users")
for row in cursor:
    print(row)

# 更新数据
conn.execute("UPDATE users SET status = 'inactive' WHERE id = '1'")

# 删除数据
conn.execute("DELETE FROM users WHERE id = '1'")

# 关闭连接
conn.close()
```

---

### 参数化查询

使用 `?` 占位符进行参数化查询，防止 SQL 注入：

```python
import kdocs_sql_model as ksql

with ksql.connect(api_token, webhook_url) as conn:
    # 插入数据
    conn.execute(
        "INSERT INTO users (id, name, age) VALUES (?, ?, ?)",
        ('1', '张三', 25)
    )
    
    # 查询数据
    cursor = conn.execute(
        "SELECT * FROM users WHERE name = ? AND age > ?",
        ('张三', 20)
    )
    rows = cursor.fetchall()
    
    # 更新数据
    conn.execute(
        "UPDATE users SET status = ? WHERE id = ?",
        ('inactive', '1')
    )
    
    # 删除数据
    conn.execute(
        "DELETE FROM users WHERE id = ?",
        ('1',)
    )
```

---

### 批量操作

使用 `executemany` 进行批量操作：

```python
import kdocs_sql_model as ksql

with ksql.connect(api_token, webhook_url) as conn:
    # 批量插入
    users = [
        ('1', '张三', 25),
        ('2', '李四', 30),
        ('3', '王五', 28),
        ('4', '赵六', 35),
    ]
    
    cursor = conn.executemany(
        "INSERT INTO users (id, name, age) VALUES (?, ?, ?)",
        users
    )
    print(f"插入了 {cursor.rowcount} 行")
    
    # 批量更新
    updates = [
        ('active', '1'),
        ('active', '2'),
    ]
    
    cursor = conn.executemany(
        "UPDATE users SET status = ? WHERE id = ?",
        updates
    )
    print(f"更新了 {cursor.rowcount} 行")
```

---

### 上下文管理器

使用 `with` 语句自动管理资源：

```python
import kdocs_sql_model as ksql

# 连接上下文管理器
with ksql.connect(api_token, webhook_url) as conn:
    # 游标上下文管理器
    with conn.cursor() as cursor:
        cursor.execute("SELECT * FROM users")
        for row in cursor:
            print(row)
    # 游标自动关闭
# 连接自动关闭

print(f"连接已关闭: {conn.closed}")  # True
```

---

### 字典格式获取

使用字典格式获取数据，更直观：

```python
import kdocs_sql_model as ksql

with ksql.connect(api_token, webhook_url) as conn:
    cursor = conn.execute("SELECT * FROM users")
    
    # 获取单行（字典格式）
    row = cursor.fetchone_dict()
    print(f"ID: {row['id']}, Name: {row['name']}")
    
    # 获取所有行（字典格式）
    cursor = conn.execute("SELECT * FROM users")
    rows = cursor.fetchall_dict()
    for row in rows:
        print(f"ID: {row['id']}, Name: {row['name']}, Age: {row['age']}")
```

---

### DDL 操作

数据定义语言操作：

```python
import kdocs_sql_model as ksql

with ksql.connect(api_token, webhook_url) as conn:
    # 创建表
    conn.execute("CREATE TABLE products (id, name, price, stock)")
    
    # 添加列
    conn.execute("ALTER TABLE products ADD COLUMN category")
    
    # 重命名列
    conn.execute("ALTER TABLE products RENAME COLUMN category TO type")
    
    # 删除列
    conn.execute("ALTER TABLE products DROP COLUMN type")
    
    # 重命名表
    conn.execute("RENAME TABLE products TO items")
    
    # 清空表数据
    conn.execute("TRUNCATE TABLE items")
    
    # 删除表
    conn.execute("DROP TABLE items")
```

---

### 便捷方法

Connection 类提供了丰富的便捷方法，简化常见操作：

#### SELECT 查询

```python
import kdocs_sql_model as ksql

with ksql.connect(api_token, webhook_url) as conn:
    # 查询所有列
    cursor = conn.select("users")
    
    # 查询指定列
    cursor = conn.select("users", ["id", "name"])
    
    # 带条件查询
    cursor = conn.select("users", where="age > '25'")
    
    # 排序
    cursor = conn.select("users", order_by="age DESC")
    
    # 分页
    cursor = conn.select("users", limit=10, offset=0)
    
    # 组合使用
    cursor = conn.select("users", ["name", "age"], 
                         where="status = 'active'", 
                         order_by="age DESC", 
                         limit=5)
```

#### INSERT 插入

```python
with ksql.connect(api_token, webhook_url) as conn:
    # 插入单行（字典）
    conn.insert("users", {"id": "1", "name": "张三", "age": "25"})
    
    # 插入多行（列表）
    conn.insert("users", [
        {"id": "2", "name": "李四", "age": "30"},
        {"id": "3", "name": "王五", "age": "28"}
    ])
```

#### UPDATE 更新

```python
with ksql.connect(api_token, webhook_url) as conn:
    # 更新数据
    conn.update("users", {"status": "inactive", "updated": "2024-01-01"}, "id = '1'")
    
    # 注意：必须指定 WHERE 条件，防止误操作
```

#### DELETE 删除

```python
with ksql.connect(api_token, webhook_url) as conn:
    # 删除数据
    conn.delete("users", "id = '1'")
    
    # 注意：必须指定 WHERE 条件，防止误操作
```

#### DDL 操作

```python
with ksql.connect(api_token, webhook_url) as conn:
    # 创建表
    conn.create_table("users", ["id", "name", "age"], if_not_exists=True)
    
    # 删除表
    conn.drop_table("users", if_exists=True)
    
    # 清空表
    conn.truncate_table("users")
    
    # 添加列
    conn.add_column("users", "email")
    
    # 删除列
    conn.drop_column("users", "temp_column")
    
    # 重命名列
    conn.rename_column("users", "name", "username")
    
    # 重命名表
    conn.rename_table("users", "members")
```

#### 聚合函数

```python
with ksql.connect(api_token, webhook_url) as conn:
    # 统计行数
    total = conn.count("users")
    active_count = conn.count("users", "status = 'active'")
    
    # 求和
    total_age = conn.sum("users", "age")
    
    # 平均值
    avg_age = conn.avg("users", "age")
    
    # 最大值/最小值
    max_age = conn.max("users", "age")
    min_age = conn.min("users", "age")
    
    # 带条件的聚合
    total_active = conn.sum("orders", "amount", "status = 'paid'")
```

---

### 聚合查询

```python
import kdocs_sql_model as ksql

with ksql.connect(api_token, webhook_url) as conn:
    # COUNT
    cursor = conn.execute("SELECT COUNT(*) AS total FROM users")
    count = cursor.fetchone()[0]
    print(f"总用户数: {count}")
    
    # SUM
    cursor = conn.execute("SELECT SUM(age) AS total_age FROM users")
    total = cursor.fetchone()[0]
    print(f"年龄总和: {total}")
    
    # AVG
    cursor = conn.execute("SELECT AVG(age) AS avg_age FROM users")
    avg = cursor.fetchone()[0]
    print(f"平均年龄: {avg}")
    
    # MAX / MIN
    cursor = conn.execute("SELECT MAX(age) AS max_age, MIN(age) AS min_age FROM users")
    row = cursor.fetchone()
    print(f"最大年龄: {row[0]}, 最小年龄: {row[1]}")
    
    # GROUP BY
    cursor = conn.execute("""
        SELECT status, COUNT(*) AS cnt
        FROM users
        GROUP BY status
    """)
    for row in cursor:
        print(f"状态 {row[0]}: {row[1]} 人")
```

---

### 分页查询

```python
import kdocs_sql_model as ksql

def paginate(conn, table, page, page_size):
    """分页查询"""
    offset = (page - 1) * page_size
    cursor = conn.execute(
        f"SELECT * FROM {table} LIMIT ? OFFSET ?",
        (page_size, offset)
    )
    return cursor.fetchall()

with ksql.connect(api_token, webhook_url) as conn:
    # 第 1 页，每页 10 条
    page1 = paginate(conn, "users", 1, 10)
    
    # 第 2 页，每页 10 条
    page2 = paginate(conn, "users", 2, 10)
```

---

### 游标滚动

```python
import kdocs_sql_model as ksql

with ksql.connect(api_token, webhook_url) as conn:
    cursor = conn.execute("SELECT * FROM users")
    
    # 获取第一行
    row1 = cursor.fetchone()
    
    # 相对滚动：跳过 2 行
    cursor.scroll(2)
    row4 = cursor.fetchone()
    
    # 绝对定位：回到开头
    cursor.scroll(0, 'absolute')
    first_row_again = cursor.fetchone()
```

### 便捷方法

Connection 类还提供了与 `kdocs_sql_client.py` 兼容的便捷方法：

#### select 方法

执行 SELECT 查询（便捷方法）

```python
# 查询所有列
cursor = conn.select("Sheet1")

# 查询指定列
cursor = conn.select("Sheet1", ["name", "age"])

# 带条件查询
cursor = conn.select("Sheet1", where="age > 20")

# 带排序
cursor = conn.select("Sheet1", order_by="age DESC")

# 带分页
cursor = conn.select("Sheet1", limit=10, offset=5)
```

---

#### insert 方法
执行 INSERT 插入（便捷方法）

```python
# 插入单行（字典）
conn.insert("Sheet1", {"name": "张三", "age": 25})

# 插入多行（列表）
conn.insert("Sheet1", [
    {"name": "张三", "age": 25},
    {"name": "李四", "age": 30}
])
```
---

#### update 方法
执行 UPDATE 更新（便捷方法）

```python
conn.update("Sheet1", {"status": "active"}, "id = '1'")
```
---

#### delete 方法
执行 DELETE 删除（便捷方法）

```python
conn.delete("Sheet1", "id = '1'")
```
---

#### create_table 方法
创建表（便捷方法）

```python
conn.create_table("users", ["id", "name", "age"], if_not_exists=True)
```
---

#### drop_table 方法
删除表（便捷方法）

```python
conn.drop_table("users", if_exists=True)
```
---

#### truncate_table 方法
清空表数据（便捷方法）

```python
conn.truncate_table("users")
```
---

#### add_column 方法
添加列（便捷方法）

```python
conn.add_column("users", "email")
```
---

#### drop_column 方法
删除列（便捷方法）

```python
conn.drop_column("users", "temp_column")
```
---

#### rename_column 方法
重命名列（便捷方法）

```python
conn.rename_column("users", "name", "username")
```
---

#### rename_table 方法
重命名表（便捷方法）

```python
conn.rename_table("users", "members")
```
---

#### count 方法
统计行数（便捷方法）

```python
total = conn.count("Sheet1")
active = conn.count("Sheet1", "status = 'active'")
```
---

#### sum 方法
求和（便捷方法）

```python
total = conn.sum("orders", "amount")
total = conn.sum("orders", "amount", "status = 'paid'")
```
---

#### avg 方法
求平均值（便捷方法）

```python
avg = conn.avg("employees", "salary")
```
---

#### max 方法
求最大值（便捷方法）

```python
max_val = conn.max("products", "price")
```
---

#### min 方法
求最小值（便捷方法）

```python
min_val = conn.min("products", "price")
```
---

## 与 sqlite3 的对比

### 相同点

| 特性 | sqlite3 | kdocs_sql_model |
|------|---------|-----------------|
| connect() | ✅ | ✅ |
| cursor() | ✅ | ✅ |
| execute() | ✅ | ✅ |
| executemany() | ✅ | ✅ |
| executescript() | ✅ | ✅ |
| fetchone() | ✅ | ✅ |
| fetchmany() | ✅ | ✅ |
| fetchall() | ✅ | ✅ |
| 参数化查询 | ✅ (?) | ✅ (?) |
| 上下文管理器 | ✅ | ✅ |
| 游标迭代 | ✅ | ✅ |

### 不同点

| 特性 | sqlite3 | kdocs_sql_model |
|------|---------|-----------------|
| 事务 | 支持 | 不支持（空操作） |
| lastrowid | 返回最后插入ID | 始终返回 None |
| 表列表 | 支持 | 不支持 |
| row_factory | 支持 | 暂不支持 |
| 字典获取 | 需设置 row_factory | 直接支持 `fetchone_dict()` |
| 数据存储 | 本地文件 | 云端表格 |

### 迁移指南

从 sqlite3 迁移到 kdocs_sql_model 非常简单：

```python
# sqlite3
import sqlite3
conn = sqlite3.connect("database.db")

# kdocs_sql_model
import kdocs_sql_model as ksql
conn = ksql.connect(api_token, webhook_url)

# 其他代码基本不变！
```

---

## 最佳实践

### 1. 使用上下文管理器

```python
# 推荐
with ksql.connect(api_token, webhook_url) as conn:
    # 操作数据库
    pass

# 不推荐
conn = ksql.connect(api_token, webhook_url)
# ... 操作数据库
conn.close()  # 可能忘记关闭
```

### 2. 使用参数化查询

```python
# 推荐：参数化查询
cursor = conn.execute("SELECT * FROM users WHERE name = ?", (name,))

# 不推荐：字符串拼接（有 SQL 注入风险）
cursor = conn.execute(f"SELECT * FROM users WHERE name = '{name}'")
```

### 3. 批量操作优于循环

```python
# 推荐：批量操作
conn.executemany(
    "INSERT INTO users (id, name) VALUES (?, ?)",
    users
)

# 不推荐：循环单条操作
for user in users:
    conn.execute("INSERT INTO users (id, name) VALUES (?, ?)", user)
```

### 4. 使用 LIMIT 限制返回行数

```python
# 推荐
cursor = conn.execute("SELECT * FROM users LIMIT 100")

# 不推荐（可能返回大量数据）
cursor = conn.execute("SELECT * FROM users")
```

### 5. 异常处理

```python
try:
    cursor = conn.execute("SELECT * FROM users")
except ksql.OperationalError as e:
    print(f"SQL 错误: {e}")
except ksql.KDocsSQLError as e:
    print(f"数据库错误: {e}")
```

---

## 常见问题

### Q: 如何获取表名列表？

A: KDocsSQL 不支持 `SHOW TABLES`，您需要知道表名才能查询。表名通常对应金山文档中的工作表名称。

### Q: 为什么 commit() 和 rollback() 没有效果？

A: KDocsSQL 不支持事务，这两个方法为空操作，仅为保持 API 兼容性而存在。

### Q: 如何处理特殊字符？

A: 使用参数化查询，模块会自动处理特殊字符（包括单引号、中文等）：

```python
# 自动处理单引号
conn.execute("INSERT INTO users (name) VALUES (?)", ("O'Brien",))
```

### Q: 数据类型如何处理？

A: KDocsSQL 中所有数据以字符串形式存储。模块会自动将 Python 类型转换为字符串：

| Python 类型 | 转换方式 |
|-------------|----------|
| None | NULL |
| bool | '1' / '0' |
| int/float | '数值' |
| str | '字符串'（自动转义） |

### Q: 如何判断查询是否成功？

A: 查询失败会抛出 `OperationalError` 异常：

```python
try:
    cursor = conn.execute("SELECT * FROM users")
    rows = cursor.fetchall()
except ksql.OperationalError as e:
    print(f"查询失败: {e}")
```

### Q: 游标可以重用吗？

A: 可以，每次 `execute()` 会重置游标状态：

```python
cursor = conn.cursor()

cursor.execute("SELECT * FROM users")
rows1 = cursor.fetchall()

cursor.execute("SELECT * FROM products")
rows2 = cursor.fetchall()
```

---

## 相关文档

- [KDocsSQL SQL 语法参考](../docs/sql-reference.md)
- [KDocsSQL 函数参考](../docs/functions.md)
- [KDocsSQL 限制说明](../docs/limitations.md)

---

---

## 更新日志

### v1.0.0

- 初始版本
- 实现与 sqlite3 兼容的 API
- 支持参数化查询
- 支持批量操作
- 支持上下文管理器
- 支持字典格式获取
- 完整的异常处理
- 添加便捷方法（与 kdocs_sql_client.py 兼容）

---

## 开发者指南

### 本地开发

```bash
# 克隆仓库
git clone https://github.com/xiaomayisjh/KDocsSQL.git
cd KDocsSQL/kdocs_sql_model

# 创建虚拟环境
python -m venv venv
source venv/bin/activate  # Linux/macOS
# 或 venv\Scripts\activate  # Windows

# 安装开发依赖
pip install -e ".[dev]"

# 运行测试
python test_kdocs_sql_model.py
```

### 发布到 PyPI

```bash
# 安装构建工具
pip install build twine

# 构建
python -m build

# 检查
twine check dist/*

# 上传到 TestPyPI（测试）
twine upload --repository testpypi dist/*

# 上传到 PyPI（正式）
twine upload dist/*
```

### 版本更新流程

1. 更新 `pyproject.toml` 中的版本号
2. 更新 `__init__.py` 中的 `__version__`
3. 更新 `README.md` 中的更新日志
4. 构建并上传新版本
