Un flux logistique envoie une nouvelle quantité dans Dataverse. La requête réussit, mais la référence de réception a disparu de la ligne ; sur une autre tentative, une quantité négative passe alors que le même contrôle la refusait auparavant. L’équipe cherche une erreur de mapping ou un plugin désactivé. Le premier élément à vérifier est plus fondamental : l’écriture atteint-elle une table standard ou une table élastique ?
Un upsert élastique n’exécute pas le même contrat qu’un upsert de table standard. Le diagnostic doit couvrir le type de table, le message reçu, les champs transmis et l’étape où les règles métier s’appliquent. Microsoft documente un remplacement des données existantes et l’absence d’appel aux messages Create et Update pour ce parcours. Un contrôle attaché uniquement à ces messages ne suffit donc pas.
Une réception devenue impossible à rattacher peut retarder le rapprochement ERP et augmenter la charge support : l’équipe doit retrouver la référence source avant de décider si dix pièces ont réellement été reçues. Le risque concerne autant la qualité des données que leur reprise. Une erreur tardive ne prouve pas que l’écriture a été annulée ; une relecture mal contextualisée peut ne pas montrer immédiatement l’état récent. Un exemple fictif de réception de pompes sépare ces situations, avec un programme local qui rend visibles les champs perdus, la validation oubliée et l’effet conservé après une erreur.
L’intégration API de votre système d’information doit préserver ces différences plutôt que les masquer derrière une méthode générique « sauvegarder ». Notre accompagnement pour relier Dynamics CRM et Dataverse à vos flux métier permet de qualifier ce contrat avec l’administrateur de la plateforme et les responsables de l’application source, avant d’augmenter le volume des imports.
Pour qui vérifier le contrat des tables élastiques
Un flux existant change de destination ou de méthode
Ce travail devient prioritaire lorsqu’un import passe de créations explicites à des upserts, lorsqu’une nouvelle table élastique remplace une destination standard ou lorsqu’un connecteur commun commence à écrire dans plusieurs types de tables. Le code peut conserver le même nom de fonction tandis que les effets changent. Une recette qui vérifie seulement le nombre de lignes reçues ne voit pas nécessairement cette différence.
Le périmètre retenu est une table élastique personnalisée alimentée par un système logistique. Il ne suppose pas que les tables commerciales standard Account ou Contact soient devenues élastiques. L’exemple traite des instantanés d’une réception, avec une identité stable et une quantité totale reçue. Un journal d’événements immuables ou une suite de variations additives demanderait un autre modèle.
Choisir la table avant de choisir la vitesse d’import
La documentation Microsoft sur les tables élastiques les situe notamment sur les charges importantes ou variables. Elle oriente vers les tables standard lorsque le besoin impose une forte cohérence, des relations complexes ou des transactions entre plusieurs enregistrements. Le débit n’est donc pas le seul critère de décision.
La documentation de création des tables élastiques présente le choix du type élastique au moment de créer la table. Traitez un changement de modèle comme une migration avec ses contrôles, pas comme une option de performance activée en production. Les règles et traitements qui dépendaient de l’ancienne destination doivent être réexaminés individuellement.
Ce que l’upsert change réellement
Deux parcours portant le même nom
Pour une table standard, la description Microsoft du traitement Upsert montre une recherche de la ligne, puis un appel à Update ou Create. Pour une table élastique, l’upsert applique directement les données, sans ces deux messages. La logique qui doit protéger toutes les écritures doit donc aussi couvrir Upsert.
Cette différence concerne le point d’entrée des contrôles, pas la simple présence d’un fichier de code. Un plugin peut être installé, actif et efficace sur les créations manuelles tout en ne couvrant pas le message utilisé par l’import. La preuve attendue associe le message, la table, le mode d’exécution et l’étape enregistrée. Le nom de l’assembly ou la date de son dernier déploiement ne suffit pas.
Un remplacement attend un état complet
La documentation d’utilisation des tables élastiques par le code indique qu’un upsert attend un corps complet et remplace les données existantes. Ne lui attribuez pas les garanties d’une fusion partielle des champs fournis. Un objet contenant uniquement la quantité corrigée peut donc être incompatible avec la conservation de votre état métier.
« Complet » signifie ici complet pour les données modifiables de votre contrat d’écriture. Il ne faut pas recopier aveuglément toutes les propriétés retournées par une lecture, notamment les champs système ou en lecture seule. Définissez les colonnes autorisées, celles qui doivent être présentes et celles qui restent sous une autre autorité. Une valeur absente et une valeur explicitement nulle doivent conserver des significations distinctes.
Dans un flux WMS → middleware → Dataverse, conservez le payload JSON réellement préparé pour l’API REST avec sa version de schéma. Comparez-le à l’instantané de réception émis par le WMS, puis à la ligne relue. Cette synchronisation doit expliquer à quel endroit un champ a été omis : dans la source, dans le mapping ou dans le corps transmis. Une copie du seul objet métier avant sérialisation ne suffit pas à situer la perte.
Inventorier les contrôles avant de modifier le connecteur
Relier chaque règle à son enregistrement effectif
La documentation d’enregistrement des plugins distingue les étapes, le message, la table et les modes synchrone ou asynchrone. Relevez ces informations sur la solution réellement déployée en recette. Comparez-les au message de votre requête, y compris lorsque celui-ci est choisi indirectement par une bibliothèque ou un composant d’import.
Construisez une ligne par règle métier : quantité autorisée, unité, identité de réception, statut admissible et cohérence de la révision source. Pour chacune, notez les chemins Create, Update et Upsert effectivement couverts. Une règle utilisée uniquement pour corriger l’affichage après l’écriture ne remplit pas le même rôle qu’une validation qui doit empêcher une donnée interdite d’entrer.
Ne pas confondre contrôle du client et protection de la destination
Le connecteur peut refuser un corps incomplet avant l’appel. Cette vérification donne un retour rapide et évite des requêtes inutiles, mais elle ne protège pas les autres producteurs qui écrivent dans la table. Le contrôle à la destination doit être vérifié séparément lorsque la règle s’applique à toute écriture. L’exemple Python plus bas représente seulement un contrat local ; il n’installe aucun plugin.
Attribuez la responsabilité du schéma à l’équipe Dataverse et celle de l’instantané émis au mainteneur du flux. La journalisation conserve les entrées qualifiées, le message demandé et les sorties observées avec une corrélation. Elle doit permettre de distinguer « validation non appelée » de « validation appelée mais règle incorrecte », sans recopier les secrets ni l’intégralité de dossiers sensibles.
Exemple : une réception de huit puis dix pièces
Décrire l’état qui doit survivre à la correction
La réception fictive R104 concerne le SKU POMPE-12. Sa première version contient huit pièces reçues, l’unité PIECE, le statut RECEIVED et la révision source 7. Le scénario utilise une destination de recette, un GUID fixe et la partition PARIS. Les noms de champs du programme sont pédagogiques ; ils ne correspondent pas à une table prête à l’emploi dans une organisation Microsoft.
La révision 8 porte le total reçu à dix pièces. L’instantané complet conserve la référence R104, le SKU, l’unité et le statut. Une seconde exécution de cet état doit laisser le total à dix, et non l’augmenter à vingt. Cette idempotence limitée à l’état ne suffit pas à garantir qu’un plugin de notification ou qu’une écriture ERP déclenchée par chaque tentative ne se répète pas : les effets aval demandent leur propre contrôle.
| Entrée | Défaut illustré | Décision locale |
|---|---|---|
| Total 10 seul | Champs omis perdus | Refuser le corps incomplet |
| Total −2 | Contrôle non appelé | Refuser avant écriture |
| État complet | Révision 8 cohérente | Conserver R104 et 10 pièces |
| Erreur tardive | État déjà écrit | Relire avant de reprendre |
Faire échouer le contrat incomplet
Le témoin non protégé reçoit seulement received_units: 10 et source_revision: 8. Son remplacement supprime les autres champs du dictionnaire. Le témoin protégé refuse ce corps avant de modifier l’état. Il refuse également une quantité négative, une unité CARTON, un autre SKU et une référence de réception différente, car ces valeurs ne correspondent pas au contrat choisi.
Ces refus ne définissent pas une règle logistique universelle. Une réception peut avoir un statut différent ou une unité en carton dans votre organisation. Il faut alors modifier le contrat et ses exemples avec le responsable métier. Le programme montre surtout qu’un import ne doit pas déduire les champs manquants à partir de valeurs par défaut qui changeraient silencieusement le sens de la réception.
Valider avant l’effet, sans compter sur une annulation tardive
Placer la validation au bon stade
Pour les tables élastiques, Microsoft recommande d’appliquer les validations dans un plugin synchrone enregistré en PreValidation. La documentation souligne l’absence de transaction commune entre les écritures de ce parcours et explique qu’une erreur en PostOperation ne restaure pas nécessairement l’état précédent. La règle doit être testée avant l’opération qu’elle cherche à empêcher.
Vérifiez ensuite que cette étape couvre réellement Upsert sur la table concernée. Une validation bien placée sur Create reste insuffisante si le flux utilise un autre message. La recette doit envoyer une donnée volontairement interdite par chaque chemin autorisé et montrer l’absence de modification correspondante. Une exception visible dans le journal prouve seulement qu’un composant a signalé une erreur.
Une requête en erreur peut avoir modifié la ligne
Paradoxalement, un échec remonté au connecteur peut coexister avec un état métier déjà écrit. Dans le témoin local, la réception passe à dix pièces, puis un traitement simulé après écriture lève une erreur. Le dictionnaire conserve la révision 8. Rejouer une action additive sur la seule base de cet échec créerait alors un risque que le statut technique ne permet pas d’écarter.
Le repli place ce dossier dans une file de résultats incertains. Son seuil de sortie est une relecture qualifiée de la bonne identité, suivie d’une décision sur les effets encore nécessaires. La politique de retry après un timeout doit également conserver la destination d’origine et demander une observation avant de réémettre un effet. Conservez la corrélation et les deux observations, erreur reçue et état relu. N’annoncez pas « aucune écriture » sans preuve, et ne retirez pas la validation pour faire disparaître l’erreur.
Garder la même partition pendant toute la reprise
Le GUID ne suffit pas lorsqu’une partition personnalisée existe
Microsoft précise qu’avec un partitionid personnalisé, la référence unique associe ce champ à la clé primaire ; le même GUID peut exister dans des partitions différentes. La valeur choisie pour une ligne ne se change pas ensuite. Le dossier de reprise doit donc conserver l’environnement, la table, le GUID et la partition utilisés au départ.
Le scénario retient PARIS comme valeur fictive, sans recommander ce découpage pour toute charge réelle. Une partition se choisit selon les volumes et les accès attendus, pas seulement selon un libellé pratique. Si un entrepôt change de nom, la logique d’intégration ne doit pas reconstruire automatiquement la partition historique à partir de son nouvel intitulé.
Refuser une destination reconstruite approximativement
Dans le témoin défaillant, la même réception est envoyée avec le même GUID dans LYON. Le stockage local la considère comme une autre identité et conserve deux lignes. La protection compare la destination au contexte approuvé et refuse ce changement avant l’effet. Cette comparaison exige une correspondance fiable ; elle ne découvre pas elle-même quel entrepôt aurait dû être retenu.
Une partition absente doit aussi être traitée selon le contrat de la ligne. Ne transformez pas une valeur manquante en chaîne vide ou en partition par défaut pour contourner un échec. Le parcours doit retrouver la destination initiale ou demander une décision de migration. Les règles des lignes créées sans partition personnalisée ne doivent pas être mélangées avec celles du scénario partitionné.
Relire le résultat dans le bon contexte de cohérence
Conserver le jeton de session renvoyé par l’écriture
La documentation d’utilisation des tables élastiques décrit le jeton x-ms-session-token renvoyé par les écritures et l’en-tête MSCRM.SessionToken utilisé pour une lecture Web API dans la session correspondante. Sans ce contexte, une lecture peut ne pas refléter immédiatement la modification récente. Ce jeton ne remplace ni l’authentification OAuth ni les permissions sur la ligne.
Le connecteur doit traiter sa valeur comme opaque et conserver son association avec le parcours concerné. Le programme fourni ne produit ni ne valide ce jeton : il reçoit directement l’observation à comparer. La collecte réelle, sa cohérence et la protection de son transport restent à vérifier dans votre environnement. Évitez de généraliser ce mécanisme en garantie de cohérence forte entre tous les consommateurs.
Comparer les champs attendus, pas uniquement la présence
La fermeture de R104 exige de retrouver la destination approuvée, les six champs du contrat et la révision 8 à dix pièces. Relire une ligne quelconque portant R104 ne suffit pas si l’environnement ou la partition diffère. Retrouver dix pièces sans l’unité ne prouve pas non plus que l’état soit exploitable par le traitement suivant.
Si l’observation montre encore huit pièces et la révision 7, classez l’écart avant de réémettre. Il peut venir du contexte de lecture, d’une écriture qui n’a pas abouti ou d’un autre producteur. L’exercice refuse simplement cette observation comme preuve de la cible ; il ne prétend pas déduire automatiquement laquelle de ces causes est vraie.
Exécuter trente et un contrôles locaux
Un modèle pédagogique limité aux décisions du connecteur
Téléchargez upsert_elastique.py et lancez-le avec Python standard. Le programme représente les états dans des dictionnaires et choisit explicitement le message du témoin. Il ne reproduit pas le moteur Dataverse, ses étapes internes, sa concurrence ou son stockage. Aucun SDK, plugin, compte Microsoft, jeton ou appel réseau n’est utilisé.
python3 upsert_elastique.py
# 31 contrôles réussis
# R104/POMPE-12 : 8 pièces, révision 7
# Cible : 10 pièces, révision 8
# Rejeu du même état : 10 pièces, pas 20
Les contrôles démontrent trois défauts : le corps partiel remplace des champs, une règle attachée aux mauvais messages laisse passer une quantité négative et une erreur simulée après écriture conserve l’état modifié. Ils vérifient ensuite le refus d’une destination différente, d’un champ absent ou ajouté, d’une mauvaise unité et d’une révision ancienne ou contradictoire.
Compléter par une recette native avant toute ouverture
Le contrôle de révision du programme est local et séquentiel. Il ne constitue pas une garantie contre deux producteurs concurrents qui lisent la même version puis écrivent chacun un état complet. Cette situation doit être traitée par le contrat de concurrence réellement disponible et vérifiée sur la destination. Une lecture suivie d’une écriture n’est pas automatiquement atomique.
La recette native doit aussi prouver l’enregistrement des étapes Upsert, leur validation avant effet, le comportement des champs omis et la relecture avec le contexte de session. Conservez les observations avant et après chaque requête autorisée. Une campagne locale verte réduit les erreurs de préparation ; elle ne remplace pas cette preuve Microsoft sur votre schéma, vos droits et vos plugins.
Erreurs fréquentes lors du passage à l’upsert élastique
Garder un corps partiel conçu pour un autre parcours
Un connecteur générique peut décider de n’envoyer que les champs modifiés afin de réduire la taille des requêtes. Cette optimisation doit dépendre du contrat de l’opération et du type de table. Dans notre scénario, elle retirerait référence, SKU, unité et statut de l’instantané. Le gain de quelques octets ne justifie pas la perte de contexte logistique.
Construire un corps complet par fusion avec une ancienne lecture ne résout pas automatiquement le problème. Un autre producteur peut avoir modifié l’état entre-temps. Définissez qui possède chaque champ et comment les versions sont arbitrées. Si deux équipes doivent modifier indépendamment une même ligne, le remplacement complet mérite une analyse de concurrence avant son adoption.
Envelopper plusieurs écritures et supposer leur atomicité
Les tables élastiques ne fournissent pas les transactions multi-enregistrements des tables standard. Ne concluez donc pas qu’un groupe de requêtes ou une exception commune annule toutes les modifications. L’architecture doit expliquer ce qui se passe si la réception est enregistrée tandis que son traitement aval échoue. Les deux observations doivent rester rapprochables.
Pour un processus exigeant une décision indivisible entre plusieurs objets, réexaminez le modèle et les capacités nécessaires avant de retenir la table élastique. Une compensation métier peut parfois être conçue, mais elle n’est ni instantanée ni équivalente à l’absence d’effet. Le choix doit appartenir au responsable du processus, avec des cas d’échec explicitement acceptés.
Plan d’action : qualifier une écriture avant de reprendre le lot
Geler les hypothèses qui ont changé
Choisissez un flux et une table de recette identifiés. Relevez le type de table dans l’environnement concerné, le message réellement demandé par le client et les étapes de plugin enregistrées. Conservez un exemple accepté et un exemple interdit par le métier. Une ancienne capture de configuration ou une documentation générique du connecteur ne remplace pas l’observation de cette installation.
- Nommer les champs obligatoires de l’instantané et leurs autorités respectives.
- Retrouver la correspondance environnement, table, GUID et partition de la réception.
- Identifier le contrôle qui doit refuser la quantité négative avant toute écriture.
Exercer les chemins qui semblaient équivalents
Faites valider les cas Create, Update et Upsert autorisés sur ce schéma. L’administrateur Dataverse examine le message et l’étape de validation ; le mainteneur du connecteur vérifie le corps réellement sérialisé. Gardez les différences visibles au lieu de masquer les résultats sous une réponse commune « enregistré ». La comparaison doit montrer quelle règle a été appelée et quels champs subsistent après l’opération.
Ajoutez un corps partiel, un état complet invalide, une partition incorrecte et une erreur provoquée dans un traitement de recette après écriture. Chaque essai possède son état initial, sa requête, son résultat et sa relecture. Les effets de test doivent rester maîtrisés et identifiables. Aucun résultat local du programme ne doit être présenté comme l’exécution de ces scénarios dans Dataverse.
Ouvrir une cohorte avec une reprise explicable
Avant d’augmenter le débit, faites passer un petit ensemble de réceptions dont les versions source sont connues. La taille dépend de votre charge et de votre capacité à examiner les anomalies ; aucun seuil universel n’est imposé. La sortie de cette cohorte exige une cible confirmée ou un refus expliqué pour chaque réception. Un dossier en erreur après effet conserve son état incertain jusqu’au rapprochement.
- Confirmer les champs conservés après un remplacement et après le rejeu du même état.
- Vérifier qu’une révision ancienne ne devient pas la cible approuvée d’une reprise.
- Attribuer les écarts de configuration à l’équipe Dataverse et les corps incomplets au producteur.
Documentez ensuite le passage de relais dans le runbook du support : identifiants à rechercher, journaux à consulter, propriétaire de la décision et conditions de réouverture. Le suivi quotidien doit distinguer validation refusée, résultat d’écriture inconnu et observation incohérente. Cette séparation permet de reprendre un dossier sans inventer un nouvel identifiant ni envoyer automatiquement un second effet métier.
Relier les autres causes d’échec Dataverse
Identité, cadence et contrat d’échange demandent des contrôles distincts
Le diagnostic des clés alternatives Dataverse et références ERP concerne explicitement les tables standard et les codes qui ne passent pas dans l’adressage. Il ne doit pas être appliqué tel quel à une table élastique. Le dossier sur les workers Dataverse et les limites partagées traite la cadence, une fois les décisions d’écriture rendues correctes.
Le contrat d’échange ERP, mapping et reprises précise les responsabilités entre systèmes. La migration des identifiants avec correspondance devient pertinente lorsque la destination change réellement d’identité. Elle permet de traiter cette migration comme une décision, au lieu de la cacher dans un rejeu.
Garder la distinction entre faits documentés et règles choisies
Les sources Microsoft liées dans les sections précédentes ont été consultées le 24 octobre 2026. Elles établissent les différences d’upsert, de validation, de partition et de cohérence. Le scénario R104, ses champs autorisés et sa politique de révision sont fictifs. Ils servent à rendre ces différences testables, sans attribuer à Microsoft une règle logistique particulière ni une amélioration de débit mesurée.
Le dossier d’exploitation final doit conserver cette séparation. Une limite documentée explique le comportement à attendre de la plateforme ; une règle interne exprime ce que votre organisation accepte ; une observation de recette prouve ce qui s’est produit dans votre installation. Les trois sont nécessaires pour décider d’une reprise, et aucune ne remplace les deux autres.
Conclusion : recetter le message et ses effets réels
Un upsert élastique ne se valide pas avec les seules habitudes d’une table standard. Il faut confirmer le corps complet, le message qui porte la logique métier et la validation avant l’effet. La réussite de l’import ne prouve pas à elle seule que les données conservées restent utilisables.
La réception R104 rend les écarts visibles : huit puis dix pièces, des champs omis qui disparaissent dans le témoin, une quantité négative acceptée par un contrôle non appelé et une erreur tardive qui laisse l’écriture en place. Les trente et un contrôles locaux préparent la recette ; ils ne prétendent pas certifier le comportement de votre organisation Dataverse.
L’accompagnement Dynamics CRM et Dataverse permet de rapprocher schéma, étapes de validation et contrat du connecteur avec vos équipes. Le résultat attendu est une reprise qui retrouve la même identité et explique les effets déjà produits avant toute nouvelle tentative.
Pour construire ce parcours dans l’ensemble de votre SI, Dawap vous accompagne sur vos intégrations API. Nous cadrons les échanges, les responsabilités et les preuves de fonctionnement afin que les données reçues restent cohérentes avec les décisions de votre métier.