fix: delete agent 500 error + dynamic personality + deployment guide
- Fix delete agent 500: clean up FK records (agent_llm_logs, permissions, schedules, executions, team_members) and unbind goals/tasks before delete - Remove hardcoded personality templates in Android, replace with dynamic system prompt generation from name + description - Set promptSectionsEnabled=false to bypass PromptComposer for personality - Add Tencent Cloud Linux deployment guide (Docker Compose) - Accumulated backend service updates, frontend UI fixes, Android app changes Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
670
backend/docs/API_DOCUMENTATION.md
Normal file
670
backend/docs/API_DOCUMENTATION.md
Normal file
@@ -0,0 +1,670 @@
|
||||
# API 文档
|
||||
|
||||
## 概述
|
||||
|
||||
天工智能体平台提供RESTful API和WebSocket API,支持工作流管理、执行管理、数据源管理等功能。
|
||||
|
||||
**Base URL**: `http://localhost:8037` 或 `http://101.43.95.130:8037`
|
||||
|
||||
**API版本**: v1
|
||||
|
||||
**文档地址**:
|
||||
- Swagger UI: `http://localhost:8037/docs`
|
||||
- ReDoc: `http://localhost:8037/redoc`
|
||||
|
||||
## 认证
|
||||
|
||||
大部分API需要JWT认证。认证流程:
|
||||
|
||||
1. 用户注册或登录获取token
|
||||
2. 在请求头中添加:`Authorization: Bearer <token>`
|
||||
|
||||
### 获取Token
|
||||
|
||||
```http
|
||||
POST /api/v1/auth/login
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
|
||||
username=your_username&password=your_password
|
||||
```
|
||||
|
||||
**响应**:
|
||||
```json
|
||||
{
|
||||
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
||||
"token_type": "bearer"
|
||||
}
|
||||
```
|
||||
|
||||
## API端点
|
||||
|
||||
### 认证API (`/api/v1/auth`)
|
||||
|
||||
#### 用户注册
|
||||
```http
|
||||
POST /api/v1/auth/register
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"username": "testuser",
|
||||
"email": "test@example.com",
|
||||
"password": "password123"
|
||||
}
|
||||
```
|
||||
|
||||
**响应**: 201 Created
|
||||
```json
|
||||
{
|
||||
"id": "uuid",
|
||||
"username": "testuser",
|
||||
"email": "test@example.com",
|
||||
"role": "user",
|
||||
"created_at": "2024-01-01T00:00:00"
|
||||
}
|
||||
```
|
||||
|
||||
#### 用户登录
|
||||
```http
|
||||
POST /api/v1/auth/login
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
|
||||
username=testuser&password=password123
|
||||
```
|
||||
|
||||
**响应**: 200 OK
|
||||
```json
|
||||
{
|
||||
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
||||
"token_type": "bearer"
|
||||
}
|
||||
```
|
||||
|
||||
#### 获取当前用户信息
|
||||
```http
|
||||
GET /api/v1/auth/me
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
**响应**: 200 OK
|
||||
```json
|
||||
{
|
||||
"id": "uuid",
|
||||
"username": "testuser",
|
||||
"email": "test@example.com",
|
||||
"role": "user"
|
||||
}
|
||||
```
|
||||
|
||||
### 工作流API (`/api/v1/workflows`)
|
||||
|
||||
#### 获取工作流列表
|
||||
```http
|
||||
GET /api/v1/workflows?skip=0&limit=10&search=关键词&status=draft&sort_by=created_at&sort_order=desc
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
**查询参数**:
|
||||
- `skip`: 跳过记录数(分页,默认0)
|
||||
- `limit`: 每页记录数(默认100,最大100)
|
||||
- `search`: 搜索关键词(按名称或描述搜索)
|
||||
- `status`: 状态筛选(draft/published/running/stopped)
|
||||
- `sort_by`: 排序字段(name/created_at/updated_at)
|
||||
- `sort_order`: 排序方向(asc/desc)
|
||||
|
||||
**响应**: 200 OK
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": "uuid",
|
||||
"name": "工作流名称",
|
||||
"description": "描述",
|
||||
"nodes": [...],
|
||||
"edges": [...],
|
||||
"version": 1,
|
||||
"status": "draft",
|
||||
"created_at": "2024-01-01T00:00:00"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
#### 创建工作流
|
||||
```http
|
||||
POST /api/v1/workflows
|
||||
Authorization: Bearer <token>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"name": "工作流名称",
|
||||
"description": "描述",
|
||||
"nodes": [
|
||||
{
|
||||
"id": "start-1",
|
||||
"type": "start",
|
||||
"position": {"x": 0, "y": 0},
|
||||
"data": {"label": "开始"}
|
||||
}
|
||||
],
|
||||
"edges": []
|
||||
}
|
||||
```
|
||||
|
||||
**响应**: 201 Created
|
||||
|
||||
#### 获取工作流详情
|
||||
```http
|
||||
GET /api/v1/workflows/{workflow_id}
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
**响应**: 200 OK
|
||||
|
||||
#### 更新工作流
|
||||
```http
|
||||
PUT /api/v1/workflows/{workflow_id}
|
||||
Authorization: Bearer <token>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"name": "更新后的名称",
|
||||
"description": "更新后的描述",
|
||||
"nodes": [...],
|
||||
"edges": [...]
|
||||
}
|
||||
```
|
||||
|
||||
**响应**: 200 OK
|
||||
|
||||
#### 删除工作流
|
||||
```http
|
||||
DELETE /api/v1/workflows/{workflow_id}
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
**响应**: 200 OK
|
||||
```json
|
||||
{
|
||||
"message": "工作流已删除"
|
||||
}
|
||||
```
|
||||
|
||||
#### 执行工作流
|
||||
```http
|
||||
POST /api/v1/workflows/{workflow_id}/execute
|
||||
Authorization: Bearer <token>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"input_data": {
|
||||
"key": "value"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**响应**: 201 Created
|
||||
```json
|
||||
{
|
||||
"id": "execution_id",
|
||||
"workflow_id": "workflow_id",
|
||||
"status": "pending",
|
||||
"task_id": "celery_task_id"
|
||||
}
|
||||
```
|
||||
|
||||
#### 验证工作流
|
||||
```http
|
||||
POST /api/v1/workflows/validate
|
||||
Authorization: Bearer <token>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"name": "工作流名称",
|
||||
"nodes": [...],
|
||||
"edges": [...]
|
||||
}
|
||||
```
|
||||
|
||||
**响应**: 200 OK
|
||||
```json
|
||||
{
|
||||
"valid": true,
|
||||
"errors": [],
|
||||
"warnings": []
|
||||
}
|
||||
```
|
||||
|
||||
#### 获取工作流模板列表
|
||||
```http
|
||||
GET /api/v1/workflows/templates
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
#### 从模板创建工作流
|
||||
```http
|
||||
POST /api/v1/workflows/templates/{template_id}/create?name=工作流名称&description=描述
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
#### 导出工作流
|
||||
```http
|
||||
GET /api/v1/workflows/{workflow_id}/export
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
**响应**: 200 OK
|
||||
```json
|
||||
{
|
||||
"workflow": {...},
|
||||
"exported_at": "2024-01-01T00:00:00"
|
||||
}
|
||||
```
|
||||
|
||||
#### 导入工作流
|
||||
```http
|
||||
POST /api/v1/workflows/import
|
||||
Authorization: Bearer <token>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"workflow": {...}
|
||||
}
|
||||
```
|
||||
|
||||
#### 获取工作流版本列表
|
||||
```http
|
||||
GET /api/v1/workflows/{workflow_id}/versions
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
#### 获取工作流版本详情
|
||||
```http
|
||||
GET /api/v1/workflows/{workflow_id}/versions/{version}
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
#### 回滚工作流版本
|
||||
```http
|
||||
POST /api/v1/workflows/{workflow_id}/versions/{version}/rollback
|
||||
Authorization: Bearer <token>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"comment": "回滚原因"
|
||||
}
|
||||
```
|
||||
|
||||
### 执行管理API (`/api/v1/executions`)
|
||||
|
||||
#### 创建执行任务
|
||||
```http
|
||||
POST /api/v1/executions
|
||||
Authorization: Bearer <token>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"workflow_id": "workflow_id",
|
||||
"input_data": {
|
||||
"key": "value"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**响应**: 201 Created
|
||||
|
||||
#### 获取执行记录列表
|
||||
```http
|
||||
GET /api/v1/executions?skip=0&limit=10&workflow_id=uuid&status=completed&search=关键词
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
**查询参数**:
|
||||
- `skip`: 跳过记录数(分页)
|
||||
- `limit`: 每页记录数(最大100)
|
||||
- `workflow_id`: 工作流ID筛选
|
||||
- `status`: 状态筛选(pending/running/completed/failed)
|
||||
- `search`: 搜索关键词
|
||||
|
||||
**响应**: 200 OK
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": "uuid",
|
||||
"workflow_id": "uuid",
|
||||
"status": "completed",
|
||||
"input_data": {...},
|
||||
"output_data": {...},
|
||||
"execution_time": 1234,
|
||||
"created_at": "2024-01-01T00:00:00"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
#### 获取执行详情
|
||||
```http
|
||||
GET /api/v1/executions/{execution_id}
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
**响应**: 200 OK
|
||||
|
||||
#### 获取执行状态
|
||||
```http
|
||||
GET /api/v1/executions/{execution_id}/status
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
**响应**: 200 OK
|
||||
```json
|
||||
{
|
||||
"status": "running",
|
||||
"progress": 50,
|
||||
"current_node": "llm-1"
|
||||
}
|
||||
```
|
||||
|
||||
### 执行日志API (`/api/v1/execution-logs`)
|
||||
|
||||
#### 获取执行日志
|
||||
```http
|
||||
GET /api/v1/execution-logs/executions/{execution_id}?level=info&node_id=node-1&skip=0&limit=100
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
**查询参数**:
|
||||
- `level`: 日志级别筛选(info/warn/error/debug)
|
||||
- `node_id`: 节点ID筛选
|
||||
- `skip`: 跳过记录数
|
||||
- `limit`: 每页记录数
|
||||
|
||||
**响应**: 200 OK
|
||||
```json
|
||||
{
|
||||
"logs": [
|
||||
{
|
||||
"id": "uuid",
|
||||
"node_id": "node-1",
|
||||
"node_type": "llm",
|
||||
"level": "info",
|
||||
"message": "节点开始执行",
|
||||
"timestamp": "2024-01-01T00:00:00",
|
||||
"duration_ms": 1234
|
||||
}
|
||||
],
|
||||
"total": 100,
|
||||
"skip": 0,
|
||||
"limit": 100
|
||||
}
|
||||
```
|
||||
|
||||
#### 获取执行日志摘要
|
||||
```http
|
||||
GET /api/v1/execution-logs/executions/{execution_id}/summary
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
**响应**: 200 OK
|
||||
```json
|
||||
{
|
||||
"total_logs": 100,
|
||||
"level_stats": {
|
||||
"info": 80,
|
||||
"warn": 10,
|
||||
"error": 5,
|
||||
"debug": 5
|
||||
},
|
||||
"node_stats": [
|
||||
{
|
||||
"node_id": "node-1",
|
||||
"node_type": "llm",
|
||||
"log_count": 10,
|
||||
"total_duration_ms": 5000
|
||||
}
|
||||
],
|
||||
"error_logs": [...]
|
||||
}
|
||||
```
|
||||
|
||||
### 数据源API (`/api/v1/data-sources`)
|
||||
|
||||
#### 获取数据源列表
|
||||
```http
|
||||
GET /api/v1/data-sources?skip=0&limit=10&type=mysql&status=active
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
#### 创建数据源
|
||||
```http
|
||||
POST /api/v1/data-sources
|
||||
Authorization: Bearer <token>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"name": "MySQL数据源",
|
||||
"type": "mysql",
|
||||
"description": "描述",
|
||||
"config": {
|
||||
"host": "localhost",
|
||||
"port": 3306,
|
||||
"database": "test",
|
||||
"username": "user",
|
||||
"password": "password"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 获取数据源详情
|
||||
```http
|
||||
GET /api/v1/data-sources/{data_source_id}
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
#### 更新数据源
|
||||
```http
|
||||
PUT /api/v1/data-sources/{data_source_id}
|
||||
Authorization: Bearer <token>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"name": "更新后的名称",
|
||||
"config": {...}
|
||||
}
|
||||
```
|
||||
|
||||
#### 删除数据源
|
||||
```http
|
||||
DELETE /api/v1/data-sources/{data_source_id}
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
#### 测试数据源连接
|
||||
```http
|
||||
POST /api/v1/data-sources/{data_source_id}/test
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
**响应**: 200 OK
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"message": "连接成功"
|
||||
}
|
||||
```
|
||||
|
||||
#### 查询数据源数据
|
||||
```http
|
||||
POST /api/v1/data-sources/{data_source_id}/query
|
||||
Authorization: Bearer <token>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"query": "SELECT * FROM table LIMIT 10"
|
||||
}
|
||||
```
|
||||
|
||||
**响应**: 200 OK
|
||||
```json
|
||||
{
|
||||
"data": [...],
|
||||
"count": 10
|
||||
}
|
||||
```
|
||||
|
||||
### WebSocket API
|
||||
|
||||
#### 连接WebSocket
|
||||
```javascript
|
||||
const ws = new WebSocket('ws://localhost:8037/api/v1/ws/executions/{execution_id}?token=<token>');
|
||||
```
|
||||
|
||||
#### 接收消息
|
||||
```json
|
||||
{
|
||||
"type": "status",
|
||||
"data": {
|
||||
"status": "running",
|
||||
"progress": 50,
|
||||
"current_node": "llm-1"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 错误码
|
||||
|
||||
| 状态码 | 说明 |
|
||||
|--------|------|
|
||||
| 200 | 成功 |
|
||||
| 201 | 创建成功 |
|
||||
| 400 | 请求参数错误 |
|
||||
| 401 | 未授权(需要登录) |
|
||||
| 403 | 禁止访问(权限不足) |
|
||||
| 404 | 资源不存在 |
|
||||
| 422 | 验证错误 |
|
||||
| 500 | 服务器内部错误 |
|
||||
|
||||
## 错误响应格式
|
||||
|
||||
```json
|
||||
{
|
||||
"detail": "错误描述",
|
||||
"error_code": "ERROR_CODE",
|
||||
"status_code": 400
|
||||
}
|
||||
```
|
||||
|
||||
## 节点类型
|
||||
|
||||
### 支持的节点类型
|
||||
|
||||
- `start` - 开始节点
|
||||
- `input` - 输入节点
|
||||
- `llm` - LLM节点(调用AI模型)
|
||||
- `condition` - 条件节点(条件判断)
|
||||
- `transform` - 转换节点(数据转换)
|
||||
- `loop` - 循环节点(循环处理)
|
||||
- `agent` - Agent节点(执行智能Agent)
|
||||
- `output` - 输出节点
|
||||
- `end` - 结束节点
|
||||
|
||||
### LLM节点配置
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "llm-1",
|
||||
"type": "llm",
|
||||
"data": {
|
||||
"provider": "deepseek",
|
||||
"model": "deepseek-chat",
|
||||
"prompt": "请回答:{input}",
|
||||
"temperature": 0.7,
|
||||
"max_tokens": 1000
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 条件节点配置
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "condition-1",
|
||||
"type": "condition",
|
||||
"data": {
|
||||
"expression": "{value} > 10"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 循环节点配置
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "loop-1",
|
||||
"type": "loop",
|
||||
"data": {
|
||||
"items_path": "items",
|
||||
"item_variable": "item",
|
||||
"error_handling": "continue"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 数据源类型
|
||||
|
||||
支持的数据源类型:
|
||||
|
||||
- `mysql` - MySQL数据库
|
||||
- `postgresql` - PostgreSQL数据库
|
||||
- `api` - RESTful API
|
||||
- `json` - JSON文件
|
||||
|
||||
## 示例
|
||||
|
||||
### 完整工作流示例
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "文本处理工作流",
|
||||
"description": "处理用户输入的文本",
|
||||
"nodes": [
|
||||
{
|
||||
"id": "start-1",
|
||||
"type": "start",
|
||||
"position": {"x": 0, "y": 0},
|
||||
"data": {"label": "开始"}
|
||||
},
|
||||
{
|
||||
"id": "llm-1",
|
||||
"type": "llm",
|
||||
"position": {"x": 200, "y": 0},
|
||||
"data": {
|
||||
"label": "LLM处理",
|
||||
"provider": "deepseek",
|
||||
"model": "deepseek-chat",
|
||||
"prompt": "请总结以下文本:{input}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "end-1",
|
||||
"type": "end",
|
||||
"position": {"x": 400, "y": 0},
|
||||
"data": {"label": "结束"}
|
||||
}
|
||||
],
|
||||
"edges": [
|
||||
{
|
||||
"id": "e1",
|
||||
"source": "start-1",
|
||||
"target": "llm-1"
|
||||
},
|
||||
{
|
||||
"id": "e2",
|
||||
"source": "llm-1",
|
||||
"target": "end-1"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 更多信息
|
||||
|
||||
详细的API文档请访问:
|
||||
- Swagger UI: `http://localhost:8037/docs`
|
||||
- ReDoc: `http://localhost:8037/redoc`
|
||||
156
backend/docs/README_ALEMBIC.md
Normal file
156
backend/docs/README_ALEMBIC.md
Normal file
@@ -0,0 +1,156 @@
|
||||
# Alembic 数据库迁移使用说明
|
||||
|
||||
## 概述
|
||||
|
||||
本项目使用 Alembic 进行数据库版本管理和迁移。Alembic 是 SQLAlchemy 的数据库迁移工具,可以自动生成迁移脚本并管理数据库结构变更。
|
||||
|
||||
## 目录结构
|
||||
|
||||
```
|
||||
backend/
|
||||
├── alembic/
|
||||
│ ├── versions/ # 迁移脚本目录
|
||||
│ │ └── 001_initial_migration.py
|
||||
│ ├── env.py # Alembic 环境配置
|
||||
│ └── script.py.mako # 迁移脚本模板
|
||||
├── alembic.ini # Alembic 配置文件
|
||||
└── migrations/ # 手动SQL脚本(备用)
|
||||
```
|
||||
|
||||
## 基本命令
|
||||
|
||||
### 1. 创建新的迁移脚本
|
||||
|
||||
```bash
|
||||
# 自动生成迁移脚本(推荐)
|
||||
alembic revision --autogenerate -m "描述信息"
|
||||
|
||||
# 手动创建空迁移脚本
|
||||
alembic revision -m "描述信息"
|
||||
```
|
||||
|
||||
### 2. 执行迁移
|
||||
|
||||
```bash
|
||||
# 升级到最新版本
|
||||
alembic upgrade head
|
||||
|
||||
# 升级到指定版本
|
||||
alembic upgrade <revision>
|
||||
|
||||
# 降级到指定版本
|
||||
alembic downgrade <revision>
|
||||
|
||||
# 降级一个版本
|
||||
alembic downgrade -1
|
||||
```
|
||||
|
||||
### 3. 查看迁移历史
|
||||
|
||||
```bash
|
||||
# 查看所有迁移版本
|
||||
alembic history
|
||||
|
||||
# 查看当前数据库版本
|
||||
alembic current
|
||||
|
||||
# 查看待执行的迁移
|
||||
alembic heads
|
||||
```
|
||||
|
||||
## 使用流程
|
||||
|
||||
### 首次使用(初始化数据库)
|
||||
|
||||
1. 确保数据库已创建:
|
||||
```sql
|
||||
CREATE DATABASE IF NOT EXISTS agent_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
```
|
||||
|
||||
2. 执行初始迁移:
|
||||
```bash
|
||||
alembic upgrade head
|
||||
```
|
||||
|
||||
### 修改模型后创建迁移
|
||||
|
||||
1. 修改 `backend/app/models/` 中的模型文件
|
||||
|
||||
2. 自动生成迁移脚本:
|
||||
```bash
|
||||
alembic revision --autogenerate -m "添加新字段"
|
||||
```
|
||||
|
||||
3. 检查生成的迁移脚本(`alembic/versions/` 目录)
|
||||
|
||||
4. 执行迁移:
|
||||
```bash
|
||||
alembic upgrade head
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **模型导入**:确保 `alembic/env.py` 中导入了所有模型,这样 Alembic 才能检测到模型变更。
|
||||
|
||||
2. **迁移脚本检查**:自动生成的迁移脚本可能不完美,需要手动检查和调整:
|
||||
- 检查索引创建/删除
|
||||
- 检查外键约束
|
||||
- 检查默认值设置
|
||||
- 检查字符集和排序规则
|
||||
|
||||
3. **生产环境**:
|
||||
- 在生产环境执行迁移前,务必先备份数据库
|
||||
- 在测试环境充分测试迁移脚本
|
||||
- 考虑数据迁移的兼容性
|
||||
|
||||
4. **回滚**:如果迁移出现问题,可以使用 `alembic downgrade` 回滚到之前的版本。
|
||||
|
||||
## 常见问题
|
||||
|
||||
### 1. 迁移脚本检测不到模型变更
|
||||
|
||||
**原因**:模型没有被正确导入
|
||||
|
||||
**解决**:检查 `alembic/env.py` 中的模型导入,确保所有模型都被导入。
|
||||
|
||||
### 2. 迁移执行失败
|
||||
|
||||
**原因**:可能是数据库连接问题、权限问题或迁移脚本错误
|
||||
|
||||
**解决**:
|
||||
- 检查数据库连接配置
|
||||
- 检查数据库用户权限
|
||||
- 查看错误日志,修复迁移脚本
|
||||
|
||||
### 3. 迁移冲突
|
||||
|
||||
**原因**:多人同时创建迁移脚本导致版本冲突
|
||||
|
||||
**解决**:
|
||||
- 使用 `alembic merge` 合并分支
|
||||
- 或者手动解决冲突,调整 `down_revision`
|
||||
|
||||
## 与手动SQL脚本的关系
|
||||
|
||||
项目中的 `backend/migrations/` 目录包含手动SQL脚本,这些脚本用于:
|
||||
- 快速初始化数据库(不依赖Alembic)
|
||||
- 特定场景的数据库操作
|
||||
- 数据迁移脚本
|
||||
|
||||
**建议**:优先使用 Alembic 进行数据库结构管理,手动SQL脚本作为补充。
|
||||
|
||||
## 示例
|
||||
|
||||
### 添加新表
|
||||
|
||||
1. 在 `app/models/` 中创建新模型
|
||||
2. 运行 `alembic revision --autogenerate -m "添加新表"`
|
||||
3. 检查生成的迁移脚本
|
||||
4. 运行 `alembic upgrade head`
|
||||
|
||||
### 修改现有表
|
||||
|
||||
1. 修改模型定义
|
||||
2. 运行 `alembic revision --autogenerate -m "修改表结构"`
|
||||
3. 检查生成的迁移脚本(可能需要手动调整)
|
||||
4. 运行 `alembic upgrade head`
|
||||
Reference in New Issue
Block a user