# Migration Base de Données Access → MySQL - Documentation Complète

## 📋 Résumé Exécutif

Cette documentation couvre la migration complète de la base de données de gestion RH d'Microsoft Access vers MySQL 8.0.

**État actuel:** ✅ Migration des données complètement terminée  
**Étape actuelle:** Validation des relations et ajout des contraintes d'intégrité  
**Prochaines étapes:** Nettoyage des orphelins et optimisations finales

---

## 🏗️ Architecture de la Solution

### Structure de Dossiers
```
ExportAccess/
├── RH/                    (16 fichiers - données employés, contrats, classifications)
├── Absences/              (3 fichiers - gestion des absences)
├── Sante/                 (6 fichiers - visites médicales, CPAM, mutuelle)
├── Alertes/               (5 fichiers - systèmes d'alerte automatisés)
├── Discipline/            (2 fichiers - sanctions, infractions)
├── Admin/                 (8 fichiers - paramètres, administrateurs, documents)
├── Orga/                  (4 fichiers - secteurs, établissements)
├── Divers/                (5 fichiers - matériel, plans, motifs de sortie)
├── Paie/                  (1 fichier - fichiers de paie)
└── Planning/              (2 fichiers - équipes de nuit, planning)
```

### Fichiers de Scripts Créés

| Fichier | Utilité | Exécution |
|---------|---------|-----------|
| `convert_xlsx_to_csv.py` | Convertit tous les XLSX en CSV | Ligne de commande |
| `normalize_all_csvs.py` | Normalise dates, décimales, booléens pour MySQL | Ligne de commande |
| `import_csvs_to_mysql.py` | Import automatique de tous les CSV en base | Ligne de commande |
| `analyze_fk_relationships.py` | Analyse les relations de FK possibles | Ligne de commande |
| `audit_orphelins.py` | Génère un rapport détaillé sur les données orphelines | Ligne de commande |
| `validate_sql.py` | Valide la syntaxe du schéma SQL | Ligne de commande |
| `CREATE_TABLE.sql` | Schéma complet de la base (56 tables) | Docker/MySQL |
| `add_foreign_keys.sql` | Script original de FK (anglais) | MySQL |
| `ajouter_cles_etrangeres_FR.sql` | Script de FK en français commenté | MySQL |
| `audit_orphelins.md` | Rapport d'audit détaillé des données orphelines | Documentation |

---

## 📊 Statistiques de Migration

### Données Importées
- **52 fichiers CSV convertis** depuis XLSX Access
- **21,600+ lignes de données** importées dans 56 tables
- **100% de succès** à la conversion et normalisation

### Répartition par Domaine
| Domaine | Fichiers | Lignes | Tables |
|---------|----------|--------|--------|
| RH (Ressources Humaines) | 16 | 2,814 | 13 |
| Alertes | 5 | 12,831 | 5 |
| Santé (Médecine du travail) | 6 | 1,062 | 5 |
| Absences | 3 | 3,049 | 3 |
| Discipline | 2 | 784 | 2 |
| Admin | 8 | 124 | 8 |
| Divers | 5 | 497 | 6 |
| Orga (Organisation) | 4 | 22 | 4 |
| Paie | 1 | 179 | 1 |
| Planning | 2 | 426 | 2 |
| **TOTAL** | **52** | **21,620** | **56** |

---

## 🔄 Pipeline de Conversion

### Phase 1: Conversion XLSX → CSV
```bash
.venv\Scripts\python.exe convert_xlsx_to_csv.py
```
**Résultat:** 52 fichiers CSV créés avec encodage UTF-8 BOM

### Phase 2: Normalisation des Données
```bash
.venv\Scripts\python.exe normalize_all_csvs.py
```
**Traitements appliqués:**
- Dates: `15-janv.-24` → `2024-01-15 00:00:00`
- Décimales: `11,32` → `11.32`
- Booléens: `OUI/NON/TRUE/FALSE` → `1/0`
- En-têtes: Suppression accents, conversion underscores

**Résultat:** 52 fichiers .bak créés, données normalisées en place

### Phase 3: Import en Base de Données
```bash
.venv\Scripts\python.exe import_csvs_to_mysql.py --truncate
```
**Résultat:** Toutes les tables remplies automatiquement, mapping CSV→table par nom

### Phase 4: Validation des Relations
```bash
.venv\Scripts\python.exe analyze_fk_relationships.py
```
**Résultat:** Détection de 8 relations FK potentielles

### Phase 5: Audit des Orphelins
```bash
.venv\Scripts\python.exe audit_orphelins.py
```
**Résultat:** Génération du rapport `audit_orphelins.md`

---

## ⚠️ Problèmes Identifiés et Solutions

### Problème 1: ID Auto-Générés vs IDs Source
**Description:** Les PK MySQL sont auto-générées (1, 2, 3...) mais les colonnes sources conservent les IDs originaux d'Access (5524, 5525...). Cela crée des orphelins.

**Symptômes:**
- `contrats.ID_Contrat` → `contrats.id`: 92.3% d'orphelins
- `contrats.Id_Salarie` → `employes.id`: 30.3% d'orphelins

**Solutions possibles:**
1. Utiliser les colonnes sources comme cibles des FK (remapping)
2. Nettoyer les données orphelines
3. Accepter les FK avec `SET NULL` pour les cas manquants

### Problème 2: Doublons dans les Colonnes Sources
**Description:** Les colonnes source contiennent des doublons, empêchant les contraintes UNIQUE.

**Exemple:** `contrats.id_contrat` a plusieurs lignes avec la même valeur

**Solution:** Créer des indices réguliers à la place d'indices UNIQUE

### Problème 3: Taux Élevé de Données Orphelines
**Description:** Certaines relations ont plus de 40% d'orphelins.

**Causes probables:**
- Données corrompues dans Access
- Importation partielle ou sélective
- Suppressions d'enregistrements après export

**Action requise:** Audit manuel de la source Access avant finalisation

---

## 🔐 Clés Étrangères Ajoutées (Sans Risque)

Les FK suivantes ont été ajoutées avec succès (0% d'orphelins):

```sql
ALTER TABLE `administrateurs` 
  ADD CONSTRAINT `fk_administrateurs_id_administrateurs` 
  FOREIGN KEY (`id_administrateurs`) REFERENCES `administrateurs`(`id`);

ALTER TABLE `classifications` 
  ADD CONSTRAINT `fk_classifications_id_classification` 
  FOREIGN KEY (`id_classification`) REFERENCES `classifications`(`id`);

ALTER TABLE `diplomes` 
  ADD CONSTRAINT `fk_diplomes_id_salarie` 
  FOREIGN KEY (`id_salarie`) REFERENCES `employes`(`id`);
```

---

## 🎯 Recommandations Prioritaires

### Court Terme (Semaine 1)
1. **Vérifier les données orphelines** dans Access
2. **Nettoyer les 5 orphelins** d'avenants_contrat (facile)
3. **Ajouter la FK:** `avenants_contrat.id_contrat` → `contrats.id_contrat`

### Moyen Terme (Semaine 2-3)
1. **Enquêter sur les 768 orphelins** de `contrats.Id_Salarie`
2. **Supprimer ou corriger** les contrats sans employé
3. **Comprendre le problème d'ID** pour `contrats.ID_Contrat`

### Long Terme (Mois 1)
1. **Réimporter les données** avec mapping d'ID approprié (optionnel)
2. **Ajouter les FK restantes** une fois les données nettoyées
3. **Mettre en place des validations** côté application

---

## 🛠️ Commandes Utiles

### Vérifier le nombre de lignes par table
```bash
docker exec -i mysql-db mysql -uroot -prootpass app_db -e "SELECT TABLE_NAME, TABLE_ROWS FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='app_db' ORDER BY TABLE_ROWS DESC;"
```

### Compter les orphelins d'une relation
```bash
docker exec -i mysql-db mysql -uroot -prootpass app_db -e "SELECT COUNT(DISTINCT t1.id_salarie) FROM contrats t1 LEFT JOIN employes t2 ON t1.Id_Salarie = t2.id WHERE t2.id IS NULL;"
```

### Afficher des exemples d'orphelins
```bash
docker exec -i mysql-db mysql -uroot -prootpass app_db -e "SELECT id, Id_Salarie FROM contrats WHERE Id_Salarie NOT IN (SELECT id FROM employes) LIMIT 5;"
```

### Relancer l'import (reset complet)
```bash
docker exec -i mysql-db mysql -uroot -prootpass -e "DROP DATABASE IF EXISTS app_db; CREATE DATABASE app_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
Get-Content .\db\schema\CREATE_TABLE.sql | docker exec -i mysql-db mysql -uroot -prootpass app_db
.venv\Scripts\python.exe import_csvs_to_mysql.py --truncate
```

---

## 📝 Notes Importantes

- **Encodage:** Tous les fichiers CSV utilisent UTF-8 BOM pour préserver les caractères accentués
- **Sauvegardes:** Les fichiers `.bak` ont été créés avant la normalisation
- **Transactions:** L'import utilise des transactions (rollback sur erreur)
- **Environnement:** Utilise les variables d'env: `MYSQL_HOST`, `MYSQL_USER`, `MYSQL_PASSWORD`, `MYSQL_DATABASE`

---

## 📞 Support

Pour toute question sur la migration:
1. Consulter le rapport `audit_orphelins.md` pour les détails des données orphelines
2. Vérifier les fichiers `.bak` pour comparer les données avant/après normalisation
3. Revoir les scripts Python avec les commentaires inclus

---

**Dernière mise à jour:** 13 mai 2026  
**Statut:** ✅ Migration complète - Nettoyage des orphelins en cours
