sql-server-table-reconciliation

Par github · awesome-copilot

À utiliser pour : comparer des tables SQL Server entre instances, valider une migration de données, vérifier des pipelines ETL, détecter des incohérences de lignes, identifier une dérive de schéma, générer un rapport de réconciliation, comparer production et staging. Utilise le driver mssql-python avec Apache Arrow pour un transfert et une comparaison de données en colonnes haute performance.

npx skills add https://github.com/github/awesome-copilot --skill sql-server-table-reconciliation

Rapprochement de tables SQL Server

Comparez des tables identiques sur deux instances SQL Server en utilisant Python avec le driver mssql-python et Apache Arrow. Détectez les lignes manquantes, les incompatibilités de colonnes, la dérive de schéma et générez un rapport de rapprochement.

Workflow

  1. Collecter les détails de connexion pour la source et la cible
  2. Identifier la clé primaire / clé composite
  3. Détecter les différences de schéma
  4. Extraire les données via Arrow pour un transfert columnar efficace
  5. Comparer les lignes et colonnes
  6. Générer un rapport de rapprochement

Collecter les entrées

Paramètre Requis Description
Serveur source Oui SQL Server source (ex. prod-server.database.windows.net)
Base de données source Oui Nom de la base de données source
Serveur cible Oui SQL Server cible (ex. staging-server.database.windows.net)
Base de données cible Oui Nom de la base de données cible
Tables Oui Noms schema.table séparés par des virgules, ou wildcard schema.* (ex. dbo.Orders,dbo.Items ou dbo.*)
Mode d'auth Oui sql (utilisateur/mot de passe) ou entra (Azure AD/token)
Clé primaire Détection auto Colonne(s) formant l'identité de la ligne. Détection auto à partir des métadonnées si non fourni.
Colonnes à comparer Toutes Sous-ensemble de colonnes, ou toutes les colonnes non-PK
Taille de chunk 100000 Lignes par batch pour les grandes tables
Format de sortie console console, csv, parquet, ou json

Script fourni

La logique de rapprochement est fournie sous forme de script autonome à scripts/reconcile.py. Invoquez-le avec les arguments appropriés selon les entrées utilisateur :

python scripts/reconcile.py \
    --source-server <source_server> \
    --source-database <source_database> \
    --target-server <target_server> \
    --target-database <target_database> \
    --tables "<table_spec>" \
    --auth <sql|entra> \
    --chunk-size <chunk_size> \
    --output <console|csv|json>

Arguments optionnels

Argument Description
--primary-key Colonnes PK séparées par des virgules. Omettez pour la détection auto.
--columns Colonnes séparées par des virgules à comparer. Omettez pour comparer toutes les colonnes non-PK.

Exemples d'invocation

Table unique avec auth SQL :

python scripts/reconcile.py \
    --source-server prod-server.database.windows.net \
    --source-database ProdDB \
    --target-server staging-server.database.windows.net \
    --target-database StagingDB \
    --tables "dbo.Orders" \
    --auth sql \
    --output console

Wildcard avec auth Entra et sortie CSV :

python scripts/reconcile.py \
    --source-server prod-server.database.windows.net \
    --source-database ProdDB \
    --target-server staging-server.database.windows.net \
    --target-database StagingDB \
    --tables "dbo.*" \
    --auth entra \
    --output csv

Prérequis

Installez les packages requis avant d'exécuter :

pip install mssql-python pyarrow pandas

Règles de comparaison

  • Normaliser les types avant comparaison : convertir les décimales à la même précision, trimmer les chaînes, normaliser datetime en UTC
  • Gestion des NULL : NULL == NULL est considéré comme une correspondance (les deux côtés manquants = pas de diff)
  • Ignorer l'ordre des lignes : toujours comparer par jonction PK, jamais positionnellement
  • Grandes tables : extraction par chunks avec OFFSET/FETCH ou partitionnement ROW_NUMBER()

Optimisation basée sur hash (pour grandes tables)

Quand la table a >1M lignes, générez un pré-check hash :

SELECT {pk_cols},
       HASHBYTES('SHA2_256', CONCAT_WS('|', col1, col2, ...)) AS row_hash
FROM {table}

Comparez d'abord les hashs ; récupérez les lignes complètes uniquement pour les hashs mal appariés. Cela réduit significativement le transfert de données.

Format du rapport

Reconciling dbo.EMPLOYEES...
Reconciling dbo.DEPARTMENTS...
Reconciling dbo.JOBS...

--- dbo.EMPLOYEES ---
  Source: 107  Target: 107
  Missing: 0  Extra: 0  Mismatches: 0
  Result: ✓ IDENTICAL

--- dbo.DEPARTMENTS ---
  Source: 27  Target: 27
  Missing: 0  Extra: 0  Mismatches: 3
  Result: ✗ DIFFERENCES FOUND

--- dbo.JOBS ---
  Source: 19  Target: 19
  Missing: 0  Extra: 0  Mismatches: 0
  Result: ✓ IDENTICAL

=== Summary: 2 passed, 1 failed, 0 skipped / 3 tables ===

Quand une table unique est fournie, incluez le détail complet (dérive de schéma, exemples de lignes, incompatibilités). Avec plusieurs tables, utilisez le format compact par table ci-dessus avec le détail complet uniquement pour les tables avec statut FAIL.

Considérations de performance

Scénario Stratégie
< 100K lignes Extraction Arrow unique, comparaison pandas en mémoire
100K–1M lignes Extraction par chunks (batches 100K), comparaison en streaming
> 1M lignes Pré-check hash → récupérer uniquement les lignes mal appariées
Tables larges (100+ cols) Comparer PK + hash d'abord, approndir colonnes spécifiques en cas de mismatch
Réseau contraint Utiliser format Arrow columnar (10-50x plus petit que ligne par ligne)

Contraintes

  • Toujours utiliser le driver mssql-python (pas pyodbc, pymssql)
  • Toujours utiliser Apache Arrow via cursor (cursor.arrow()) pour l'extraction de données
  • La connexion DOIT utiliser le format chaîne de connexion, pas les arguments de mot-clé (kwargs comme encrypt=True causent des erreurs)
  • Ne jamais comparer sans identifier d'abord la PK — demandez à l'utilisateur si la détection auto échoue
  • Gérer les défaillances de connexion avec grâce et logique de retry
  • Ne jamais coder en dur les credentials dans les scripts générés — utiliser os.environ / getpass (variables env : MSSQL_USER, MSSQL_PASSWORD)
  • Ne pas afficher les credentials dans la sortie ou les logs
  • Utiliser des requêtes paramétrées (placeholders ?) pour les lookups de métadonnées — ne jamais interpoler l'entrée utilisateur en SQL via f-string

Skills similaires