run-migration-fix-timestamp.ts 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. import { AppDataSource } from '../models/index.js';
  2. import { logger } from '../utils/logger.js';
  3. async function runMigration() {
  4. try {
  5. // 初始化数据库连接
  6. await AppDataSource.initialize();
  7. logger.info('[Migration] Database connected');
  8. // 设置时区
  9. await AppDataSource.query("SET time_zone = '+08:00'");
  10. logger.info('[Migration] Timezone set to +08:00');
  11. // 检查当前表结构
  12. const currentStructure = await AppDataSource.query(`
  13. SELECT
  14. COLUMN_NAME,
  15. DATA_TYPE
  16. FROM INFORMATION_SCHEMA.COLUMNS
  17. WHERE TABLE_SCHEMA = DATABASE()
  18. AND TABLE_NAME = 'user_day_statistics'
  19. AND COLUMN_NAME IN ('created_at', 'updated_at')
  20. `);
  21. const needsMigration = currentStructure.some((col: any) => col.DATA_TYPE === 'timestamp');
  22. if (!needsMigration) {
  23. logger.info('[Migration] Table already uses DATETIME type, skipping migration');
  24. } else {
  25. logger.info('[Migration] Converting TIMESTAMP to DATETIME...');
  26. // 执行迁移:修改 created_at
  27. logger.info('[Migration] Modifying created_at column...');
  28. await AppDataSource.query(`
  29. ALTER TABLE user_day_statistics
  30. MODIFY COLUMN created_at DATETIME NULL
  31. `);
  32. await AppDataSource.query(`
  33. ALTER TABLE user_day_statistics
  34. MODIFY COLUMN created_at DATETIME DEFAULT CURRENT_TIMESTAMP
  35. `);
  36. logger.info('[Migration] created_at converted to DATETIME');
  37. // 执行迁移:修改 updated_at
  38. logger.info('[Migration] Modifying updated_at column...');
  39. await AppDataSource.query(`
  40. ALTER TABLE user_day_statistics
  41. MODIFY COLUMN updated_at DATETIME NULL
  42. `);
  43. await AppDataSource.query(`
  44. ALTER TABLE user_day_statistics
  45. MODIFY COLUMN updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
  46. `);
  47. logger.info('[Migration] updated_at converted to DATETIME');
  48. }
  49. // 验证结果:查询表结构
  50. logger.info('[Migration] Verifying table structure...');
  51. const tableInfo = await AppDataSource.query(`
  52. SELECT
  53. COLUMN_NAME,
  54. DATA_TYPE,
  55. COLUMN_DEFAULT,
  56. IS_NULLABLE
  57. FROM INFORMATION_SCHEMA.COLUMNS
  58. WHERE TABLE_SCHEMA = DATABASE()
  59. AND TABLE_NAME = 'user_day_statistics'
  60. AND COLUMN_NAME IN ('created_at', 'updated_at')
  61. ORDER BY COLUMN_NAME
  62. `);
  63. logger.info('[Migration] Table structure:');
  64. for (const col of tableInfo) {
  65. logger.info(
  66. `[Migration] ${col.COLUMN_NAME}: ${col.DATA_TYPE} (nullable: ${col.IS_NULLABLE}, default: ${col.COLUMN_DEFAULT || 'NULL'})`
  67. );
  68. }
  69. // 验证结果:查询几条数据
  70. logger.info('[Migration] Verifying data format...');
  71. const sampleData = await AppDataSource.query(`
  72. SELECT
  73. id,
  74. account_id,
  75. record_date,
  76. created_at,
  77. updated_at
  78. FROM user_day_statistics
  79. ORDER BY id DESC
  80. LIMIT 5
  81. `);
  82. logger.info('[Migration] Sample data:');
  83. for (const row of sampleData) {
  84. logger.info(
  85. `[Migration] ID ${row.id}: created_at=${row.created_at}, updated_at=${row.updated_at}`
  86. );
  87. }
  88. logger.info('[Migration] Migration completed successfully!');
  89. process.exit(0);
  90. } catch (error) {
  91. logger.error('[Migration] Migration failed:', error);
  92. process.exit(1);
  93. } finally {
  94. if (AppDataSource.isInitialized) {
  95. await AppDataSource.destroy();
  96. }
  97. }
  98. }
  99. void runMigration();