From 5efbfd90fb024df3d9c2f4878cd30fcf7ba50c5c Mon Sep 17 00:00:00 2001 From: qingss0 Date: Fri, 24 Jul 2026 06:16:57 +0800 Subject: [PATCH] =?UTF-8?q?new:=20=E6=96=B0=E5=BB=BA=E6=96=87=E4=BB=B6=20R?= =?UTF-8?q?EADME.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: qingss0 --- sqlite3/README.md | 248 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 248 insertions(+) create mode 100644 sqlite3/README.md diff --git a/sqlite3/README.md b/sqlite3/README.md new file mode 100644 index 0000000..8e72e1f --- /dev/null +++ b/sqlite3/README.md @@ -0,0 +1,248 @@ +# Flask SQLite 执行服务 + +一个轻量级的 Flask HTTP 服务,用于安全地执行带参数的 SQLite SQL 语句,支持 `?` 和命名参数占位符,杜绝 SQL 注入。 + +## 功能特点 + +- 通过 JSON 接口发送 SQL 和参数 +- 强制使用参数绑定(`execute(sql, params)`),无 SQL 注入风险 +- 统一返回格式,所有语句执行结果均包含 `data` 数组 +- 自动事务管理,异常时回滚 +- 无外部依赖(除 Flask),即开即用 + +## 快速开始 + +### 环境要求 + +- Python 3.7+ +- pip + +### 安装依赖 + +```bash +pip install flask +``` + +### 启动服务 + +```bash +python app.py +``` + +服务默认监听 `http://127.0.0.1:5000`,数据库文件 `database.db` 会在首次连接时自动创建(你需要预先建表或通过接口执行 `CREATE TABLE`)。 + +## API 文档 + +### 执行 SQL 语句 + +**端点**:`POST /execute` + +**请求格式**:`Content-Type: application/json` + +```json +{ + "sql": "SQL 语句,使用 ? 或 :key 作为占位符", + "params": [] 或 {} +} +``` + +- `sql`:待执行的 SQL 语句(仅允许单条语句) +- `params`:参数列表 `[值1, 值2, ...]` 或参数字典 `{"key": 值}` + +**成功响应**: + +```json +{ + "success": true, + "data": [] // 查询结果数组,每条记录为字典;非查询语句返回空数组 +} +``` + +**错误响应**: + +```json +{ + "success": false, + "error": "错误描述" +} +``` + +## 使用示例 + +以下示例均通过 `curl` 和 Python `requests` 库演示。 + +### 1. 创建数据表 + +```bash +curl -X POST http://localhost:5000/execute \ + -H "Content-Type: application/json" \ + -d '{"sql": "CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, age INTEGER)"}' +``` + +Python 版本: + +```python +import requests + +url = "http://localhost:5000/execute" +payload = { + "sql": "CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, age INTEGER)" +} +resp = requests.post(url, json=payload) +print(resp.json()) # {"success": true, "data": []} +``` + +### 2. 插入数据(使用 `?` 占位符) + +```bash +curl -X POST http://localhost:5000/execute \ + -H "Content-Type: application/json" \ + -d '{"sql": "INSERT INTO users (name, age) VALUES (?, ?)", "params": ["Alice", 30]}' +``` + +Python 版本: + +```python +payload = { + "sql": "INSERT INTO users (name, age) VALUES (?, ?)", + "params": ["Bob", 25] +} +resp = requests.post(url, json=payload) +print(resp.json()) # {"success": true, "data": []} +``` + +### 3. 插入数据(使用命名参数 `:key`) + +```bash +curl -X POST http://localhost:5000/execute \ + -H "Content-Type: application/json" \ + -d '{"sql": "INSERT INTO users (name, age) VALUES (:name, :age)", "params": {"name": "Charlie", "age": 28}}' +``` + +### 4. 查询全部数据 + +```bash +curl -X POST http://localhost:5000/execute \ + -H "Content-Type: application/json" \ + -d '{"sql": "SELECT * FROM users"}' +``` + +响应示例: + +```json +{ + "success": true, + "data": [ + {"id": 1, "name": "Alice", "age": 30}, + {"id": 2, "name": "Bob", "age": 25}, + {"id": 3, "name": "Charlie", "age": 28} + ] +} +``` + +Python 版本: + +```python +payload = {"sql": "SELECT * FROM users"} +resp = requests.post(url, json=payload) +users = resp.json()["data"] +for user in users: + print(user["name"], user["age"]) +``` + +### 5. 按条件查询 + +```bash +curl -X POST http://localhost:5000/execute \ + -H "Content-Type: application/json" \ + -d '{"sql": "SELECT * FROM users WHERE age > ?", "params": [26]}' +``` + +Python 版本: + +```python +payload = { + "sql": "SELECT * FROM users WHERE age > :min_age", + "params": {"min_age": 26} +} +resp = requests.post(url, json=payload) +print(resp.json()["data"]) +``` + +### 6. 更新数据 + +```bash +curl -X POST http://localhost:5000/execute \ + -H "Content-Type: application/json" \ + -d '{"sql": "UPDATE users SET age = ? WHERE name = ?", "params": [31, "Alice"]}' +``` + +Python 版本: + +```python +payload = { + "sql": "UPDATE users SET age = :new_age WHERE id = :user_id", + "params": {"new_age": 26, "user_id": 2} +} +resp = requests.post(url, json=payload) +print(resp.json()) # {"success": true, "data": []} +``` + +### 7. 删除数据 + +```bash +curl -X POST http://localhost:5000/execute \ + -H "Content-Type: application/json" \ + -d '{"sql": "DELETE FROM users WHERE id = ?", "params": [3]}' +``` + +Python 版本: + +```python +payload = { + "sql": "DELETE FROM users WHERE name = :name", + "params": {"name": "Charlie"} +} +resp = requests.post(url, json=payload) +print(resp.json()) +``` + +### 8. 错误处理示例 + +当 SQL 或参数错误时,返回明确的错误信息: + +```bash +curl -X POST http://localhost:5000/execute \ + -H "Content-Type: application/json" \ + -d '{"sql": "SELECT * FROM nonexistent_table"}' +``` + +响应: + +```json +{ + "success": false, + "error": "no such table: nonexistent_table" +} +``` + +## 安全机制 + +1. **参数绑定**:使用 `sqlite3` 官方推荐的 `execute(sql, params)` 方式传参,参数值与 SQL 结构完全分离。 +2. **单语句执行**:`sqlite3.execute()` 仅执行第一条语句,无法通过分号注入多条命令。 +3. **错误回滚**:若执行过程中出现异常,已修改的数据会回滚,确保数据一致性。 + +## 项目结构 + +``` +. +├── app.py # 主程序 +└── README.md # 本文档 +``` + +数据库文件 `database.db` 会在运行时自动生成。 + +## 注意事项 + +- 该服务无认证机制,请勿直接暴露在公网;如需使用,请配合反向代理并增加鉴权。 +- 所有写操作(INSERT/UPDATE/DELETE 等)会立即提交,且 `data` 字段固定为空数组。 \ No newline at end of file