Files
steel_prices_service/scripts/README-IMPORT.md
2026-01-06 18:00:43 +08:00

308 lines
7.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 数据导入脚本使用说明
## 概述
`scripts/import-data.js` 已升级,现在支持两种数据导入模式:
1. **本地文件模式** (`local`): 从 `data/` 目录的 JSON 文件导入
2. **API 接口模式** (`api`): 从 `commonApi.js` 定义的接口实时获取数据
## 接口映射关系
| 接口端点 | 数据来源 | 对应文件 | 数据来源标识 |
|---------|---------|---------|------------|
| `DEFAULT` | 云南钢协 | 刚协指导价.json | 云南钢协 |
| `BACKUP` | 我的钢铁 | 钢材网架.json | 我的钢铁 |
| `EXTENDED` | 德钢指导价 | 钢厂指导价.json | 德钢指导价 |
## 使用方法
### 1. 本地文件导入(默认模式)
```bash
# 方式 1: 显式指定模式
node scripts/import-data.js local
# 方式 2: 使用默认模式(省略参数)
npm run db:import
# 或
node scripts/import-data.js
```
**功能说明:**
-`data/` 目录读取所有 JSON 文件
- 依次导入:刚协指导价.json、钢材网架.json、钢厂指导价.json
- 跳过不存在的文件
### 2. API 接口导入
#### 2.1 从所有 API 接口导入
```bash
# 使用默认参数(今天到一年后,每页 10 万条)
node scripts/import-data.js api
# 指定日期范围
node scripts/import-data.js api --startDate 2025-01-01 --endDate 2025-12-31
# 指定每页数量
node scripts/import-data.js api --pageSize 50000
# 组合参数
node scripts/import-data.js api --startDate 2025-01-01 --endDate 2025-12-31 --pageSize 100000
```
**执行流程:**
1. 依次调用 DEFAULT、BACKUP、EXTENDED 三个接口
2. 自动获取 Token
3. 批量导入数据(每批 1000 条)
4. 显示导入进度和统计信息
#### 2.2 从单个 API 接口导入
```bash
# 仅导入云南钢协数据DEFAULT 接口)
node scripts/import-data.js single-api DEFAULT
# 仅导入我的钢铁数据BACKUP 接口)
node scripts/import-data.js single-api BACKUP
# 仅导入德钢指导价数据EXTENDED 接口)
node scripts/import-data.js single-api EXTENDED
# 带参数的单接口导入
node scripts/import-data.js single-api DEFAULT --startDate 2025-01-01 --endDate 2025-12-31
```
## 命令行参数
| 参数 | 说明 | 示例 | 默认值 |
|-----|------|-----|-------|
| `--startDate` | 查询开始日期YYYY-MM-DD | `--startDate 2025-01-01` | 今天 |
| `--endDate` | 查询结束日期YYYY-MM-DD | `--endDate 2026-01-01` | 一年后 |
| `--pageSize` | 每页数据条数 | `--pageSize 100000` | 100000 |
## 输出示例
### 本地文件导入
```
🚀 开始从本地文件导入钢材价格数据...
📄 正在读取本地文件: 刚协指导价.json
✅ 解析到 900 条有效数据
进度: 900/900 条
✅ 成功导入 900 条数据
📄 正在读取本地文件: 钢材网架.json
✅ 解析到 211 条有效数据
进度: 211/211 条
✅ 成功导入 211 条数据
📄 正在读取本地文件: 钢厂指导价.json
✅ 解析到 29987 条有效数据
进度: 1000/29987 条
进度: 2000/29987 条
...
进度: 29987/29987 条
✅ 成功导入 29987 条数据
==================================================
🎉 本地文件导入完成!总计导入 31098 条数据
==================================================
📊 数据库统计信息:
总记录数: 31098
平均价格: 4500.25 元/吨
最低价格: 3200 元/吨
最高价格: 5800 元/吨
✅ 脚本执行完成
```
### API 接口导入
```
🚀 开始从 API 接口导入钢材价格数据...
🌐 正在从 API 接口获取数据: DEFAULT (云南钢协)
查询参数: {
"startDate": "2025-01-06",
"endDate": "2026-01-06",
"page": 1,
"pageSize": 100000
}
🔐 正在获取 Token...
✅ Token 获取成功: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
🔄 切换到接口: 默认钢材价格查询
Page ID: PG-D615-D8E2-2FD84B8D
Menu ID: MK-A8B8-109E-13D34116
✅ 解析到 1250 条有效数据
进度: 1000/1250 条
进度: 1250/1250 条
✅ 成功导入 1250 条数据
🌐 正在从 API 接口获取数据: BACKUP (我的钢铁)
...
🌐 正在从 API 接口获取数据: EXTENDED (德钢指导价)
...
==================================================
🎉 API 接口导入完成!总计导入 15234 条数据
==================================================
📊 数据库统计信息:
总记录数: 46332
平均价格: 4450.80 元/吨
最低价格: 3100 元/吨
最高价格: 5900 元/吨
✅ 脚本执行完成
```
## 编程式调用
除了命令行调用,也可以在代码中直接使用:
```javascript
const { importFromAPI, importAllFromAPI, importAllLocalFiles } = require('./scripts/import-data');
// 方式 1: 从单个 API 接口导入
await importFromAPI('DEFAULT', {
startDate: '2025-01-01',
endDate: '2025-12-31',
pageSize: 100000
});
// 方式 2: 从所有 API 接口导入
await importAllFromAPI({
startDate: '2025-01-01',
endDate: '2025-12-31'
});
// 方式 3: 从本地文件导入
await importAllLocalFiles();
```
## 错误处理
脚本包含完善的错误处理机制:
1. **文件不存在**: 自动跳过,继续处理其他文件
2. **API 请求失败**: 显示错误信息,继续处理下一个接口
3. **数据解析失败**: 显示详细错误,不会中断整个流程
4. **数据库插入失败**: 记录错误日志,支持批量插入失败重试
## 注意事项
1. **环境变量**: 确保 `.env` 文件配置正确,包含数据库连接信息
2. **Token 管理**: API 模式会自动从 `loginApi.js` 获取 Token确保登录凭证有效
3. **网络连接**: API 模式需要稳定的网络连接
4. **数据库性能**: 批量插入每批 1000 条,大数据量导入可能需要较长时间
5. **重复数据**: 使用 `ON DUPLICATE KEY UPDATE` 策略,避免重复导入
## 故障排查
### 问题 1: Token 获取失败
```
❌ Token 获取失败: Invalid credentials
```
**解决方案:**
- 检查 `.env` 中的登录凭证
- 确认 `loginApi.js` 中的 Token 存储路径正确
- 手动运行 `node commonApi.js` 测试登录
### 问题 2: 数据库连接失败
```
❌ 价格表创建失败: Access denied for user 'root'@'localhost'
```
**解决方案:**
- 检查 `.env` 中的数据库配置
- 确认 MySQL 服务已启动
- 验证用户权限
### 问题 3: API 返回空数据
```
⚠️ 没有有效数据可导入
```
**解决方案:**
- 检查日期范围是否合理
- 确认 API 接口地址正确
- 尝试增加 `pageSize` 参数
## 最佳实践
1. **定期导入**: 使用 `node-cron` 或系统定时任务定期执行 API 导入
2. **增量更新**: 使用日期参数仅导入最新数据
3. **数据备份**: 导入前备份现有数据
4. **监控日志**: 保存导入日志用于审计和问题排查
## 示例:定时任务
使用 `node-cron` 设置每天凌晨 2 点自动导入:
```javascript
// scripts/schedule-import.js
const cron = require('node-cron');
const { exec } = require('child_process');
cron.schedule('0 2 * * *', () => {
console.log('🕰️ 开始定时导入任务...');
exec('node scripts/import-data.js api --startDate 2025-01-01 --pageSize 100000',
(error, stdout, stderr) => {
if (error) {
console.error(`执行出错: ${error}`);
return;
}
console.log(stdout);
}
);
});
console.log('✅ 定时任务已启动:每天 02:00 执行数据导入');
```
运行定时任务:
```bash
node scripts/schedule-import.js
```
## 技术细节
### 数据转换
- 原始数据格式: `rawData.data.page.result[]`
- 过滤条件: `price_date` 存在且 `hang_price > 0`
- 字段映射: 自动映射 API 字段到数据库字段
### 批量插入策略
- 批次大小: 1000 条/批
- 重复处理: 使用 `ON DUPLICATE KEY UPDATE`
- 事务支持: 每批独立事务
### 性能优化
- 批量插入优于单条插入
- 数据库索引优化 (`idx_price_date`, `idx_region_material`)
- 自动过滤无效数据,减少不必要的数据库操作
---
## 更新日志
### 2026-01-06
- ✅ 新增 API 接口导入功能
- ✅ 支持命令行参数配置
- ✅ 改进错误处理和进度显示
- ✅ 保持向后兼容性