pre-migration.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. # -*- coding: utf-8 -*-
  2. """
  3. Pre-migration script to prepare database schema for template integration
  4. This script runs BEFORE the module update to:
  5. 1. Make template_id nullable
  6. 2. Add workflow_template_id column
  7. 3. Prepare for constraint changes
  8. """
  9. import logging
  10. _logger = logging.getLogger(__name__)
  11. def migrate(cr, version):
  12. """Prepare database schema for template integration"""
  13. try:
  14. _logger.info("=" * 80)
  15. _logger.info("Starting pre-migration: Preparing database schema")
  16. _logger.info("=" * 80)
  17. # 1. Check if workflow_template_id column exists
  18. cr.execute("""
  19. SELECT column_name
  20. FROM information_schema.columns
  21. WHERE table_name = 'helpdesk_template_field'
  22. AND column_name = 'workflow_template_id'
  23. """)
  24. workflow_col_exists = cr.fetchone()
  25. if not workflow_col_exists:
  26. _logger.info("Adding workflow_template_id column to helpdesk_template_field...")
  27. cr.execute("""
  28. ALTER TABLE helpdesk_template_field
  29. ADD COLUMN workflow_template_id INTEGER
  30. """)
  31. _logger.info("✅ Column workflow_template_id added")
  32. else:
  33. _logger.info("Column workflow_template_id already exists")
  34. # 2. Add foreign key constraint if it doesn't exist
  35. cr.execute("""
  36. SELECT constraint_name
  37. FROM information_schema.table_constraints
  38. WHERE table_name = 'helpdesk_template_field'
  39. AND constraint_name = 'helpdesk_template_field_workflow_template_id_fkey'
  40. """)
  41. fk_exists = cr.fetchone()
  42. if not fk_exists:
  43. _logger.info("Adding foreign key constraint for workflow_template_id...")
  44. cr.execute("""
  45. ALTER TABLE helpdesk_template_field
  46. ADD CONSTRAINT helpdesk_template_field_workflow_template_id_fkey
  47. FOREIGN KEY (workflow_template_id)
  48. REFERENCES helpdesk_workflow_template(id)
  49. ON DELETE CASCADE
  50. """)
  51. _logger.info("✅ Foreign key constraint added")
  52. else:
  53. _logger.info("Foreign key constraint already exists")
  54. # 3. Make template_id nullable (if it's not already)
  55. cr.execute("""
  56. SELECT is_nullable
  57. FROM information_schema.columns
  58. WHERE table_name = 'helpdesk_template_field'
  59. AND column_name = 'template_id'
  60. """)
  61. template_nullable = cr.fetchone()
  62. if template_nullable and template_nullable[0] == 'NO':
  63. _logger.info("Making template_id nullable...")
  64. # First, drop the NOT NULL constraint by altering the column
  65. cr.execute("""
  66. ALTER TABLE helpdesk_template_field
  67. ALTER COLUMN template_id DROP NOT NULL
  68. """)
  69. _logger.info("✅ template_id is now nullable")
  70. else:
  71. _logger.info("template_id is already nullable")
  72. # 4. Add index on workflow_template_id for performance
  73. cr.execute("""
  74. SELECT indexname
  75. FROM pg_indexes
  76. WHERE tablename = 'helpdesk_template_field'
  77. AND indexname = 'helpdesk_template_field_workflow_template_id_index'
  78. """)
  79. index_exists = cr.fetchone()
  80. if not index_exists:
  81. _logger.info("Adding index on workflow_template_id...")
  82. cr.execute("""
  83. CREATE INDEX helpdesk_template_field_workflow_template_id_index
  84. ON helpdesk_template_field(workflow_template_id)
  85. """)
  86. _logger.info("✅ Index added")
  87. else:
  88. _logger.info("Index already exists")
  89. # 5. Add CHECK constraint to ensure only one of template_id or workflow_template_id is set
  90. cr.execute("""
  91. SELECT constraint_name
  92. FROM information_schema.table_constraints
  93. WHERE table_name = 'helpdesk_template_field'
  94. AND constraint_name = 'helpdesk_template_field_check_template_or_workflow'
  95. """)
  96. check_exists = cr.fetchone()
  97. if not check_exists:
  98. _logger.info("Adding CHECK constraint for template_or_workflow...")
  99. cr.execute("""
  100. ALTER TABLE helpdesk_template_field
  101. ADD CONSTRAINT helpdesk_template_field_check_template_or_workflow
  102. CHECK ((template_id IS NOT NULL AND workflow_template_id IS NULL)
  103. OR (template_id IS NULL AND workflow_template_id IS NOT NULL))
  104. """)
  105. _logger.info("✅ CHECK constraint added")
  106. else:
  107. _logger.info("CHECK constraint already exists")
  108. cr.commit()
  109. _logger.info("=" * 80)
  110. _logger.info("✅ Pre-migration completed successfully")
  111. _logger.info("=" * 80)
  112. except Exception as e:
  113. _logger.error(f"❌ Error in pre-migration: {e}", exc_info=True)
  114. try:
  115. cr.rollback()
  116. except Exception:
  117. pass # Ignore rollback errors
  118. # Raise to prevent module update if pre-migration fails
  119. # This ensures database is in consistent state
  120. raise