Version de développement
Cette documentation décrit la version « next » (develop), non encore publiée. Pour la version stable, basculez sur « v5 » dans l'en-tête.
Personnalisation

Personnalisation des patches

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.

Personnalisation des patches

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.

Sections des patches

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 :

Sections existantes

SectionMoment d'exécutionUtilisation typique
pre_model_syncAvant la synchronisation du schéma de la base de donnéesModifications structurelles qui doivent être appliquées avant que les modèles ne soient synchronisés
post_model_syncAprès la synchronisation du schéma, mais avant les fixtures et personnalisationsModifications 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

Nouvelle section : post_fixture_sync

La 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 :

  • Mettre à jour des données qui dépendent de champs ajoutés via des fixtures ou des Champs personnalisés
  • Appliquer des modifications sur des types de documents qui ont été étendus par des personnalisations
  • Exécuter des scripts qui nécessitent que toutes les fixtures et personnalisations soient déjà en place

Exemple d'utilisation

[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 :

  • Le patch update_schema_data s'exécute après la synchronisation du schéma, mais avant que les fixtures ne soient appliquées.
  • Le patch 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.

Structure d'un fichier patches.txt

Un 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

Bonnes pratiques

  1. Ordre des patches : Les patches dans une même section sont exécutés dans l'ordre où ils apparaissent dans le fichier.
  2. Idempotence : Un patch doit pouvoir être exécuté plusieurs fois sans causer d'erreurs ou de duplications.
  3. Compatibilité : Les patches doivent être compatibles avec les versions antérieures pour éviter les ruptures lors des mises à jour.
  4. Tests : Testez toujours vos patches dans un environnement de développement avant de les appliquer en production.

Créer un patch

Pour créer un nouveau patch :

  1. Générer le fichier : Utilisez la commande suivante pour générer un fichier de patch vide :
    bench new-patch <nom_du_patch> --app <nom_de_l_app>
    

    Exemple :
    bench new-patch backfill_custom_field_values --app myapp
    
  2. Écrire le script : Ouvrez le fichier généré dans 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
 """)
  1. Ajouter le patch à 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
    

Résultat

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 aller plus loin

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