Parcourir la source

Fix: Mejorar detección y eliminación de constraints UNIQUE antiguos

- Buscar todos los constraints UNIQUE que involucren template_id, workflow_template_id o field_id
- Usar múltiples métodos para eliminar constraints (robustez)
- Mejorar logging para debugging
odoo il y a 2 mois
Parent
commit
d936919cd4
1 fichiers modifiés avec 33 ajouts et 17 suppressions
  1. 33 17
      helpdesk_extras/migrations/18.0.1.0.12/pre-migration.py

+ 33 - 17
helpdesk_extras/migrations/18.0.1.0.12/pre-migration.py

@@ -99,27 +99,43 @@ def migrate(cr, version):
         else:
             _logger.info("Index already exists")
         
-        # 5. Drop old UNIQUE constraints if they exist (they don't work well with NULLs)
+        # 5. Drop ALL old UNIQUE constraints on helpdesk_template_field (they don't work well with NULLs)
+        # Odoo names constraints as: {table_name}_{constraint_name}
+        # We need to find and drop any UNIQUE constraints that involve template_id or workflow_template_id
         cr.execute("""
-            SELECT constraint_name 
-            FROM information_schema.table_constraints 
-            WHERE table_name = 'helpdesk_template_field' 
-            AND constraint_name IN ('helpdesk_template_field_unique_template_field', 
-                                     'helpdesk_template_field_unique_workflow_template_field')
+            SELECT DISTINCT tc.constraint_name
+            FROM information_schema.table_constraints tc
+            JOIN information_schema.key_column_usage kcu 
+                ON tc.constraint_name = kcu.constraint_name
+                AND tc.table_schema = kcu.table_schema
+            WHERE tc.table_name = 'helpdesk_template_field' 
+            AND tc.constraint_type = 'UNIQUE'
+            AND (kcu.column_name IN ('template_id', 'workflow_template_id', 'field_id'))
         """)
         old_constraints = cr.fetchall()
         
-        for constraint in old_constraints:
-            constraint_name = constraint[0]
-            _logger.info(f"Dropping old constraint: {constraint_name}...")
-            try:
-                cr.execute(f"""
-                    ALTER TABLE helpdesk_template_field 
-                    DROP CONSTRAINT IF EXISTS {constraint_name}
-                """)
-                _logger.info(f"✅ Dropped constraint: {constraint_name}")
-            except Exception as e:
-                _logger.warning(f"Could not drop constraint {constraint_name}: {e}")
+        if old_constraints:
+            _logger.info(f"Found {len(old_constraints)} UNIQUE constraint(s) to drop")
+            for constraint in old_constraints:
+                constraint_name = constraint[0]
+                _logger.info(f"Dropping old constraint: {constraint_name}...")
+                try:
+                    # Use format string with proper escaping
+                    cr.execute(f'ALTER TABLE helpdesk_template_field DROP CONSTRAINT IF EXISTS "{constraint_name}"')
+                    _logger.info(f"✅ Dropped constraint: {constraint_name}")
+                except Exception as e:
+                    _logger.warning(f"Could not drop constraint {constraint_name}: {e}")
+                    # Try alternative method
+                    try:
+                        cr.execute("""
+                            ALTER TABLE helpdesk_template_field 
+                            DROP CONSTRAINT IF EXISTS %s
+                        """, (constraint_name,))
+                        _logger.info(f"✅ Dropped constraint (method 2): {constraint_name}")
+                    except Exception as e2:
+                        _logger.error(f"Failed to drop constraint {constraint_name} with both methods: {e2}")
+        else:
+            _logger.info("No old UNIQUE constraints found to drop")
         
         # 6. Add partial unique indexes (work correctly with NULLs)
         # Index for template_id + field_id (only when template_id IS NOT NULL)