Les patches dans Dokos permettent de modifier la structure ou les données de la base lors des mises à jour. Ils sont essentiels pour garantir que les évolutions du système sont appliquées de manière cohérente et sécurisée.
Un fichier patches.txt dans une application Dokos est organisé en sections qui déterminent à quel moment du processus de migration les patches sont exécutés. Voici les sections disponibles :
| Section | Moment d'exécution | Utilisation typique |
|---|---|---|
pre_model_sync | Avant la synchronisation du schéma de la base de données | Modifications structurelles qui doivent être appliquées avant que les modèles ne soient synchronisés |
post_model_sync | Après la synchronisation du schéma, mais avant les fixtures et personnalisations | Modifications des données qui dépendent de la structure mise à jour, mais qui doivent être appliquées avant que les fixtures ne soient chargées |
post_fixture_syncLa section post_fixture_sync a été ajoutée pour permettre l'exécution de patches après la synchronisation des fixtures et des personnalisations. Cela est particulièrement utile pour :
[post_model_sync]
myapp.patches.v2_0.update_schema_data
[post_fixture_sync]
# Sécurisé : les champs ajoutés via fixtures ou Custom Fields sont disponibles
myapp.patches.v2_0.backfill_custom_field_values
Dans cet exemple :
update_schema_data s'exécute après la synchronisation du schéma, mais avant que les fixtures ne soient appliquées.backfill_custom_field_values s'exécute après que toutes les fixtures et personnalisations aient été synchronisées, ce qui permet de référencer en toute sécurité des champs ajoutés via ces mécanismes.patches.txtUn fichier patches.txt typique ressemble à ceci :
[pre_model_sync]
myapp.patches.v1_0.migrate_old_data
[post_model_sync]
myapp.patches.v1_0.update_new_fields
[post_fixture_sync]
myapp.patches.v2_0.backfill_custom_data
Pour créer un nouveau patch :
bench new-patch <nom_du_patch> --app <nom_de_l_app>
bench new-patch backfill_custom_field_values --app myapp
apps/myapp/myapp/patches/ et implémentez la logique nécessaire. Voici un exemple de patch simple :import frappe
def execute():
# Exemple : Mettre à jour un champ personnalisé ajouté via une fixture
frappe.db.sql("""
UPDATE tabCustomer
SET custom_discount_percentage = 10
WHERE custom_loyalty_status = 'Gold'
""")
3. **Ajouter le patch au fichier `patches.txt`** : Insérez le chemin du patch dans la section appropriée du fichier `patches.txt` de votre application.
## Vérifier l'exécution des patches
Pour vérifier quels patches ont été exécutés sur votre instance :
1. Allez dans **Outils de développement > Patch Log** (recherchez "Patch Log" dans la barre Awesome).
2. Vous verrez une liste de tous les patches exécutés, avec leur statut et leur date d'exécution.
## Dépannage
### Patch non exécuté
Si un patch n'est pas exécuté :
- Vérifiez que le chemin du patch dans `patches.txt` est correct.
- Assurez-vous que le patch est dans la bonne section (`pre_model_sync`, `post_model_sync`, ou `post_fixture_sync`).
- Consultez les logs de migration (`logs/migrate.log`) pour identifier d'éventuelles erreurs.
### Erreur lors de l'exécution d'un patch
Si un patch échoue :
- Vérifiez que le script est idempotent et peut être réexécuté sans causer de problèmes.
- Assurez-vous que toutes les dépendances (fixtures, champs personnalisés) sont en place avant d'exécuter le patch.
- Testez le patch dans un environnement de développement pour identifier et corriger les erreurs.
## Exemple complet
### Scénario
**Maison Verte SARL** utilise un champ personnalisé `custom_loyalty_status` sur ses fiches clients pour suivre le statut de fidélité (Bronze, Argent, Or). Lors d'une mise à jour, l'administrateur souhaite ajouter un nouveau champ `custom_discount_percentage` via une fixture, puis remplir ce champ avec des valeurs par défaut en fonction du statut de fidélité.
### Solution
1. **Ajouter le champ personnalisé** : Le champ `custom_discount_percentage` est ajouté via une fixture dans `myapp/fixtures/custom_fields.json`.
2. **Créer le patch** : Un patch est créé pour remplir le champ `custom_discount_percentage` en fonction du statut de fidélité.
```python
import frappe
def execute():
# Mettre à jour les pourcentages de réduction en fonction du statut de fidélité
frappe.db.sql("""
UPDATE `tabCustomer`
SET custom_discount_percentage =
CASE
WHEN custom_loyalty_status = 'Bronze' THEN 5
WHEN custom_loyalty_status = 'Silver' THEN 10
WHEN custom_loyalty_status = 'Gold' THEN 15
ELSE 0
END
""")
patches.txt : Le patch est ajouté dans la section post_fixture_sync pour s'assurer que le champ custom_discount_percentage est disponible.[post_fixture_sync]
myapp.patches.v2_0.backfill_discount_percentage
Après la migration, tous les clients de Maison Verte SARL auront leur champ custom_discount_percentage rempli avec les valeurs appropriées, sans que l'administrateur n'ait besoin d'intervenir manuellement.
Pour une documentation complète sur les patches et les migrations dans Dokos, consultez les ressources suivantes :
Migrations et patches — Guide complet
Créer un patch — Guide technique