quanyoumi/backend/migrations
Yvan 4920620d2c 优化验证报名信息对话框车牌号输入布局,使标签和输入框在同一行显示 2026-04-09 15:37:40 +08:00
..
0000-init-schema.js 优化验证报名信息对话框车牌号输入布局,使标签和输入框在同一行显示 2026-04-09 15:37:40 +08:00
0001-add-danmaku-fields.js 优化验证报名信息对话框车牌号输入布局,使标签和输入框在同一行显示 2026-04-09 15:37:40 +08:00
0002-add-sponsor-sortorder.js 优化验证报名信息对话框车牌号输入布局,使标签和输入框在同一行显示 2026-04-09 15:37:40 +08:00
0003-add-checkin-fields.js 优化验证报名信息对话框车牌号输入布局,使标签和输入框在同一行显示 2026-04-09 15:37:40 +08:00
0004-add-prize-table.js 优化验证报名信息对话框车牌号输入布局,使标签和输入框在同一行显示 2026-04-09 15:37:40 +08:00
README.md 优化验证报名信息对话框车牌号输入布局,使标签和输入框在同一行显示 2026-04-09 15:37:40 +08:00
index.js 优化验证报名信息对话框车牌号输入布局,使标签和输入框在同一行显示 2026-04-09 15:37:40 +08:00

README.md

数据库迁移系统

概述

本项目使用版本化的数据库迁移系统,支持增量更新和自动同步。

特性

  • 版本管理:每个迁移有唯一版本号
  • 增量执行:只执行未执行的迁移
  • 自动运行:服务器启动时自动执行迁移
  • 幂等性:重复执行不会出错
  • 迁移记录:记录所有已执行的迁移

迁移文件命名规范

XXXX-description.js
  • XXXX: 4位数字版本号如 0001, 0002
  • description: 迁移描述(使用短横线分隔)

示例:

  • 0001-add-danmaku-fields.js
  • 0002-add-user-avatar.js

创建新迁移

1. 创建迁移文件

backend/migrations/ 目录下创建新文件:

/**
 * 迁移: 添加用户头像字段
 * 版本: 0002
 * 日期: 2025-01-09
 */

module.exports = {
  async up(manager) {
    console.log('  - 添加 avatar 字段...');
    await manager.executeSql(`
      ALTER TABLE Users ADD COLUMN avatar TEXT;
    `);
  },

  async down(manager) {
    // 回滚逻辑(可选)
    console.log('  - 回滚不支持');
  }
};

2. 迁移方法

up(manager) - 升级

执行数据库变更的方法。

可用的 manager 方法:

  • executeSql(sql): 执行SQL语句
  • db: 直接访问数据库连接

down(manager) - 回滚(可选)

回滚数据库变更的方法。

注意SQLite 不支持 DROP COLUMN回滚可能需要重建表。

执行迁移

自动执行(推荐)

服务器启动时会自动执行所有未执行的迁移:

# 开发环境
cd backend
npm start

# 生产环境Docker
docker-compose up -d
# 或
docker-compose restart

手动执行

在容器内执行:

# Windows
migrate.bat

# Linux/Mac
chmod +x migrate.sh
./migrate.sh

直接在容器中执行:

docker exec quanyoumi-app node /app/backend/migrations/index.js

迁移状态

迁移执行记录保存在 migrations 表中:

SELECT * FROM migrations;

输出示例:

id | version | name                  | executed_at
---+---------+-----------------------+---------------------
1  | 1       | add-danmaku-fields    | 2025-01-09 10:30:00
2  | 2       | add-user-avatar       | 2025-01-09 11:00:00

常见问题

Q: 迁移失败怎么办?

A: 检查错误日志,修复问题后重新启动服务器。已执行的迁移不会重复执行。

Q: 如何回滚迁移?

A: 目前不支持自动回滚。如需回滚,请手动修改数据库或创建新的迁移来撤销更改。

Q: 可以修改已执行的迁移吗?

A: 不建议。已执行的迁移不应修改。如需更改,请创建新的迁移。

Q: 迁移在什么时候执行?

A: 服务器启动时自动执行。也可以手动运行 migrate.batmigrate.sh

最佳实践

  1. 版本号递增:新迁移的版本号应大于所有现有迁移
  2. 描述清晰:文件名和注释应清楚说明迁移目的
  3. 测试迁移:在开发环境测试后再部署到生产环境
  4. 幂等性:迁移应该可以安全地重复执行
  5. 小步迭代:每个迁移只做一件事,便于追踪和回滚

示例

添加新字段

module.exports = {
  async up(manager) {
    await manager.executeSql(`
      ALTER TABLE Activities ADD COLUMN featured INTEGER DEFAULT 0;
    `);
  }
};

创建新表

module.exports = {
  async up(manager) {
    await manager.executeSql(`
      CREATE TABLE IF NOT EXISTS Comments (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        activityId INTEGER NOT NULL,
        userId INTEGER NOT NULL,
        content TEXT NOT NULL,
        createdAt DATETIME DEFAULT CURRENT_TIMESTAMP
      );
    `);
  }
};

修改数据

module.exports = {
  async up(manager) {
    await manager.executeSql(`
      UPDATE Activities SET status = 'completed' WHERE endTime < datetime('now');
    `);
  }
};