IAMaîtriser l'IA générative Plan du corpus
Accueil/Applications au developpement/Refactoring et migration

03 - Refactoring et migration

Refactoriser, c est changer la forme sans changer le comportement ; tout l enjeu est de pouvoir le prouver a chaque lot.

Temps de lecture : 15 min | Niveau : Intermediaire a Avance

Ce que tu sauras faire apres

  • Poser un filet de securite avant de toucher a une seule ligne.
  • Decouper une migration en lots verifiables au lieu d un big bang.
  • Faire ecrire un "rulebook" de traduction avant de traduire quoi que ce soit.
  • Migrer un script pandas vers PySpark sans casser les resultats.
  • Migrer du SQL Oracle vers BigQuery en connaissant les pieges de dialecte.

La regle non negociable

Refactoriser = le comportement observable ne change pas.

Donc avant de commencer, tu dois pouvoir repondre a une seule question : comment je prouve que le comportement n a pas change ?

Trois reponses acceptables :

FiletQuandCommande type
Suite de tests existanteCode applicatif deja testepytest -q
Test caracterisationCode non teste (le cas le plus frequent)test qui fige la sortie actuelle
Comparaison de sortiesPipeline data, SQL, script batchdiff entre ancienne et nouvelle sortie

Si tu n as aucun des trois : commence par en fabriquer un (voir fichier 02). C est exactement ce que fait Anthropic pour ses migrations a grande echelle. La regle qu ils posent sur leur juge de conformite vaut pour ton filet a toi : "The judge must be able to evaluate both the original code and the target code on equal terms." (AI code migration)

Autrement dit : ton controle doit pouvoir tourner des deux cotes, sur l ancien comme sur le nouveau. Un test qui ne s execute que sur la nouvelle version ne prouve rien.

Template - Filet de securite avant refactoring

Fichier a refactoriser plus tard : @[CHEMIN/FICHIER]
Il n a pas de tests aujourd hui.

Etape 1 seulement : ecris des tests de caracterisation, c est-a-dire des
tests qui figent le comportement ACTUEL, meme s il est bizarre. Le but n est
pas de juger si le comportement est bon, mais de pouvoir detecter tout
changement.

Couvre :
- le chemin nominal avec [EXEMPLE_D_ENTREE_REELLE]
- les cas limites que tu identifies en lisant le code
- les erreurs levees aujourd hui

Lance `pytest -q` et montre-moi que tout passe AVANT qu on touche au code.
Ne modifie pas le code source a cette etape.

La strategie par lots

La doc Claude Code resume la methode en quatre temps :

  1. find deprecated API usage in our codebase
  2. suggest how to refactor utils.js to use modern JavaScript features
  3. refactor utils.js to use ES2024 features while maintaining the same behavior
  4. run tests for the refactored code

Et donne le conseil central : "Do refactoring in small, testable increments."

Pourquoi les petits lots

Un gros lot rate coute cher : tu ne sais pas laquelle des 40 modifications a casse quelque chose. Un lot de 3 fichiers rate se diagnostique en 2 minutes.

Anthropic decrit le meme decoupage. Leur etape 1 s appelle "Create the rulebook, dependency map, and gap inventory" : le rulebook est d abord "lookup tables that translates types and idioms between languages". Leur etape 2 s appelle "Stress-test the rules" : on traduit quelques fichiers seulement, pour verifier que les regles tiennent, avant de lancer la traduction complete a l etape 3.

Template - Inventaire et plan de lots

Objectif : [DECRIS_LA_MIGRATION_EN_UNE_PHRASE]
Perimetre : @[DOSSIER_OU_LISTE_DE_FICHIERS]

N ecris aucun code. Produis :

1. INVENTAIRE : la liste des fichiers concernes, avec pour chacun
   - le nombre de lignes
   - la difficulte estimee (facile / moyen / risque)
   - les dependances vers d autres fichiers de la liste

2. ORDRE : dans quel ordre les traiter, en commencant par ceux qui n ont
   aucune dependance

3. LOTS : regroupe-les en lots de [TAILLE_DE_LOT] fichiers maximum, chaque
   lot devant pouvoir etre teste et livre seul

4. RULEBOOK : les regles de traduction recurrentes, sous forme de tableau
   "motif avant | motif apres | piege a surveiller"

5. ZONES GRISES : les endroits ou la traduction n est pas mecanique et ou il
   faudra une decision humaine

Le point 4 est le plus rentable. Une fois le rulebook ecrit, tu le recolles dans chaque prompt de lot : le modele devient regulier d un lot a l autre.

Template - Execution d un lot

Rulebook a appliquer (ne devie pas de ces regles) :
[COLLE_ICI_LE_TABLEAU_DU_RULEBOOK]

Lot [NUMERO] : @[FICHIER_1], @[FICHIER_2], @[FICHIER_3]

Consignes :
- le comportement observable ne doit pas changer
- ne refactorise rien en dehors de ces fichiers
- marque d un commentaire `# TODO-MIGRATION: [raison]` chaque endroit ou tu
  n es pas sur, au lieu de deviner
- ne supprime aucun commentaire existant

Puis lance `[COMMANDE_DE_TEST]` et montre-moi la sortie.
Enfin, liste les TODO-MIGRATION que tu as poses.

Le marquage TODO-MIGRATION vient du process Anthropic. Leur consigne exacte : "Anything the translator can't execute confidently gets flagged with // TODO(port): <reason>". Au lieu de deviner, le modele signale ; toi, tu tranches ensuite d un seul coup sur tous les points signales. Garde toujours la meme etiquette, quelle qu elle soit : c est ce qui te permet de tous les retrouver avec un grep -rn "TODO-MIGRATION".

Le garde-fou contre le zele

Les modeles recents ont tendance a en faire trop. La doc Anthropic donne le texte a coller :

Avoid over-engineering. Only make changes that are directly requested or
clearly necessary. Keep solutions simple and focused:

- Scope: Don't add features, refactor code, or make "improvements" beyond
  what was asked.
- Documentation: Don't add docstrings, comments, or type annotations to code
  you didn't change.
- Defensive coding: Don't add error handling, fallbacks, or validation for
  scenarios that can't happen.
- Abstractions: Don't create helpers, utilities, or abstractions for
  one-time operations.

Version courte en francais, a garder sous la main :

Ne fais que ce qui est demande. Pas de fonctionnalite en plus, pas
d abstraction en plus, pas de gestion d erreur pour des cas impossibles,
pas de docstring sur du code que tu n as pas touche.

Exemple 1 : d un script pandas a PySpark

Le probleme reel

Ton script daily_sales.py tourne en pandas. Il met 40 minutes et sature la RAM depuis que le volume a triple. Tu veux passer sur Spark.

Ce qu il faut savoir avant

L API pandas sur Spark s importe ainsi (Quickstart PySpark) :

import pyspark.pandas as ps

Conversions dans les deux sens :

psdf = ps.from_pandas(pdf)   # pandas -> pandas-on-Spark
pdf = psdf.to_pandas()       # pandas-on-Spark -> pandas (ramene tout en memoire)

to_pandas() ramene tout le jeu de donnees sur le noeud pilote (le driver). Sur un gros volume, c est exactement ce que tu cherchais a eviter en passant a Spark (pyspark.pandas.DataFrame.to_pandas).

Le piege principal, cite tel quel par la doc Spark :

"Note that the data in a Spark dataframe does not preserve the natural order by default. The natural order can be preserved by setting compute.ordered_head option but it causes a performance overhead with sorting internally."

Autrement dit : tout code qui dependait de l ordre des lignes (head, index positionnel, iloc, calcul cumule sans tri explicite) peut donner un resultat different. C est la premiere chose a verifier.

Note d honnetete : l API pandas sur Spark ne vise pas 100 % de compatibilite avec pandas. Certaines fonctions n existent pas et demandent une reecriture manuelle.

La page Supported pandas API donne le detail, fonction par fonction :

  • Y : implementee, avec tous ses parametres ;
  • P : partiellement implementee, les parametres manquants sont listes ;
  • N : pas implementee.

Ouvre la page de la version de Spark que tu utilises, pas celle de latest. Fais-le avant d annoncer une date de livraison.

Template - Migration pandas vers PySpark

Script a migrer : @[CHEMIN/SCRIPT.py]
Volume actuel : [NOMBRE] lignes, [TAILLE] Go
Cible : PySpark, version [VERSION], sur [PLATEFORME]
Sortie de reference : [CHEMIN_OU_TABLE] produite par le script actuel

Etape 1 - ANALYSE, sans ecrire de code :
a) liste chaque operation pandas du script et son equivalent PySpark
b) signale toute operation qui depend de l ORDRE des lignes ou de l index
   (head, iloc, cumsum sans tri, reset_index) : ce sont les risques n 1
c) signale toute operation qui ramene tout en memoire (to_pandas, collect,
   toPandas) et dis si elle est evitable
d) signale les fonctions pandas sans equivalent direct

Etape 2 - apres ma validation seulement : ecris la version PySpark.

Etape 3 - VERIFICATION : ecris un script de comparaison qui
- lance l ancien et le nouveau sur le meme jeu de donnees de [TAILLE_ECHANTILLON]
- compare le nombre de lignes
- compare la somme de chaque colonne numerique
- compare ligne a ligne apres tri sur [CLE_DE_TRI]
- affiche les ecarts s il y en a

AVANT / APRES

Mauvais prompt :

convertis ce script pandas en pyspark

Tu obtiens du code qui compile, qui tourne, et dont personne ne sait s il donne les memes chiffres.

Prompt ameliore : celui du template ci-dessus. Il impose l analyse avant le code, il nomme explicitement le piege de l ordre, et il termine par un script de comparaison chiffree. C est la difference entre "ca marche" et "c est prouve".


Exemple 2 : du SQL Oracle vers BigQuery

Ce qu il faut savoir avant

Google publie un guide de traduction dedie : Oracle SQL translation guide. Il sert de table de correspondance entre le dialecte Oracle et GoogleSQL, et couvre notamment :

  • les equivalences de types de donnees ;
  • les fonctions d agregation et les fonctions analytiques ;
  • les fonctions de date et d heure ;
  • les fonctions mathematiques ;
  • les constructions Oracle sans equivalent direct (NVL, ROWNUM, DUAL, les sequences, MERGE, le PL/SQL).

Le guide previent lui-meme qu il n y a pas toujours de correspondance : "In some cases, there is no direct mapping between a SQL element in Oracle and BigQuery, but in most cases, you can achieve the same functionality in BigQuery using an alternative means."

Google fournit aussi deux outils, et sa doc dit lequel utiliser quand : "You can use batch SQL translation to migrate your SQL scripts in bulk, or interactive SQL translation to translate ad-hoc queries." Le traducteur par lots sert a "translate scripts written in other SQL dialects into GoogleSQL queries".

Commence par ces outils : ils font le gros du travail mecanique. L IA sert ensuite a traiter ce que le traducteur a laisse de cote.

Attention : cette page evolue et les correspondances dependent de ta version. Ne recopie aucune equivalence de memoire, et n en fais pas inventer. Fais confirmer chaque construction une par une, avec le template ci-dessous.

La methode en trois temps

  1. Traducteur automatique de Google sur tout le lot. Il traite le travail mecanique et signale ce qu il ne sait pas convertir.
  2. IA uniquement sur les requetes que le traducteur a signalees ou mal converties.
  3. Comparaison de resultats entre Oracle et BigQuery sur un echantillon.

L ordre compte : l IA coute plus cher et derive plus facilement que le traducteur. Elle passe en dernier, sur le reste.

Template - Traduction d une requete Oracle vers BigQuery

Requete Oracle a traduire vers GoogleSQL (BigQuery) :

[COLLE_ICI_TA_REQUETE_ORACLE]

Schema des tables concernees :
[COLLE_ICI_LES_COLONNES_ET_LEURS_TYPES]

Traduis-la en GoogleSQL. Puis, en dessous, donne un tableau :
| construction Oracle | equivalent GoogleSQL | difference de comportement a surveiller |

Verifie explicitement ces points, un par un :
- NVL, NVL2, DECODE
- ROWNUM et la pagination
- FROM DUAL
- les sequences et les identifiants auto-incrementes
- les fonctions de date (SYSDATE, TRUNC, ADD_MONTHS, TO_DATE)
- la concatenation de chaines et le traitement de la chaine vide
- MERGE
- les types NUMBER sans precision

Si une construction n a pas d equivalent exact, dis-le et propose deux
options avec leurs consequences. Ne choisis pas a ma place.

Le point "chaine vide" merite une mention : les moteurs SQL ne traitent pas tous '' et NULL de la meme maniere. C est une source classique d ecarts silencieux apres migration. Fais-le verifier explicitement plutot que de le supposer.

Template - Verification de parite Oracle / BigQuery

Ecris-moi les requetes de controle qui comparent l ancienne et la nouvelle
version, sur [PERIODE_DE_TEST].

Je veux, pour chaque table migree :
1. le nombre de lignes des deux cotes
2. la somme de chaque colonne numerique des deux cotes
3. le nombre de valeurs NULL par colonne des deux cotes
4. les 10 premieres cles presentes d un cote et pas de l autre

Format de sortie : une requete par controle, avec un commentaire qui dit
quel resultat attendre quand tout va bien.

Quand ca derape

Trois symptomes et leur correctif, tires de la liste des echecs classiques de la doc Claude Code :

SymptomeCorrectif
Tu corriges deux fois la meme chose sans resultat"After two failed corrections, /clear and write a better initial prompt incorporating what you learned."
Le lot produit un code plausible mais faux"Always provide verification (tests, scripts, screenshots). If you can't verify it, don't ship it."
Le modele s eparpille sur tout le repoReduis le perimetre du lot, ou passe par un sous-agent avec un perimetre explicite

Et pour les tres gros volumes, la doc decrit la mise a l echelle : generer d abord la liste des fichiers a migrer dans un fichier, puis boucler dessus en mode non interactif.

for file in $(cat files.txt); do
  claude -p "Migrate $file from Python 2 to Python 3. Return OK or FAIL." \
    --allowedTools "Edit,Bash(git commit *)"
done

Le conseil qui accompagne cet exemple : "Test on a few files, then run on all of them." Affine le prompt sur 2 ou 3 fichiers avant de lancer sur les 2000.


A retenir

  • Pas de filet, pas de refactoring. Test de caracterisation d abord si le code n est pas teste.
  • Ecris le rulebook de traduction AVANT de traduire, puis recolle-le dans chaque lot.
  • Lots courts, testes et livrables un par un. Jamais de big bang.
  • Fais marquer TODO-MIGRATION au lieu de laisser deviner, et tranche ensuite en une fois.
  • pandas vers PySpark : le risque principal est l ordre des lignes, pas la syntaxe.
  • Oracle vers BigQuery : utilise d abord les traducteurs SQL de Google, l IA ensuite sur le reste.
  • Termine toujours par une comparaison chiffree ancienne sortie / nouvelle sortie.

Sources

Corpus personnel de formation · genere le 26/09/2026 · source : 03-refactoring-et-migration.md