apply_migration.py 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. #!/usr/bin/env python
  2. """
  3. 应用数据库迁移脚本
  4. 用法:
  5. python apply_migration.py
  6. """
  7. import os
  8. import sys
  9. # 添加项目根目录到路径
  10. sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
  11. from app import create_app, db
  12. from sqlalchemy import text
  13. def apply_migration():
  14. """应用account_id字段可空的迁移"""
  15. app = create_app()
  16. with app.app_context():
  17. try:
  18. print("正在应用数据库迁移...")
  19. # 检查当前表结构
  20. result = db.engine.execute(text("PRAGMA table_info(aws_credentials)"))
  21. columns = result.fetchall()
  22. account_id_nullable = False
  23. for column in columns:
  24. if column[1] == 'account_id': # column[1] is column name
  25. account_id_nullable = column[3] == 0 # column[3] is notnull (0=nullable, 1=not null)
  26. break
  27. if account_id_nullable:
  28. print("✓ account_id字段已经是可空的")
  29. return
  30. print("正在修改account_id字段为可空...")
  31. # SQLite doesn't support ALTER COLUMN directly, so we need to recreate the table
  32. # First, create a backup of the data
  33. db.engine.execute(text("""
  34. CREATE TABLE aws_credentials_backup AS
  35. SELECT * FROM aws_credentials
  36. """))
  37. # Drop the original table
  38. db.engine.execute(text("DROP TABLE aws_credentials"))
  39. # Recreate the table with nullable account_id
  40. db.engine.execute(text("""
  41. CREATE TABLE aws_credentials (
  42. id INTEGER PRIMARY KEY,
  43. name VARCHAR(100) NOT NULL,
  44. credential_type VARCHAR(20) NOT NULL,
  45. account_id VARCHAR(12), -- Now nullable
  46. role_arn VARCHAR(255),
  47. external_id VARCHAR(255),
  48. access_key_id VARCHAR(255),
  49. secret_access_key_encrypted TEXT,
  50. created_at DATETIME,
  51. is_active BOOLEAN,
  52. CHECK (credential_type IN ('assume_role', 'access_key'))
  53. )
  54. """))
  55. # Create index on account_id
  56. db.engine.execute(text("CREATE INDEX ix_aws_credentials_account_id ON aws_credentials (account_id)"))
  57. # Restore the data
  58. db.engine.execute(text("""
  59. INSERT INTO aws_credentials
  60. SELECT * FROM aws_credentials_backup
  61. """))
  62. # Drop the backup table
  63. db.engine.execute(text("DROP TABLE aws_credentials_backup"))
  64. print("✓ 数据库迁移完成")
  65. except Exception as e:
  66. print(f"❌ 迁移失败: {e}")
  67. # Try to restore from backup if it exists
  68. try:
  69. db.engine.execute(text("DROP TABLE IF EXISTS aws_credentials"))
  70. db.engine.execute(text("ALTER TABLE aws_credentials_backup RENAME TO aws_credentials"))
  71. print("已恢复原始数据")
  72. except:
  73. pass
  74. raise
  75. if __name__ == '__main__':
  76. apply_migration()