Migration · HFSQL → PostgreSQL

Migrer une base HFSQL
vers PostgreSQL.

Vos données sont le patrimoine de votre entreprise : clients, commandes, historiques, stocks. Les garder dans HFSQL, c'est les laisser dans un format que seuls les outils PC SOFT savent bien exploiter. Nous les reprenons dans PostgreSQL, MySQL / MariaDB ou SQL Server, sans ressaisie et avec des contrôles à chaque étape.

Pourquoi quitter HFSQL ?

HFSQL, en version Classic (fichiers partagés sur le réseau) ou Client/Serveur, est la base livrée avec WinDev, WebDev et WinDev Mobile. Elle est simple à mettre en place, mais elle enferme vos données dans l'écosystème de l'éditeur : peu d'outils de reporting ou d'analyse la lisent nativement, peu d'administrateurs la connaissent, et toute nouvelle application doit passer par les mêmes outils pour y accéder.

Une base SQL standard change la donne :

MySQL / MariaDB et SQL Server sont aussi des cibles possibles, par exemple si votre système d'information les utilise déjà. La méthode décrite ici s'applique aux trois.

Équivalence des concepts HFSQL → SQL

Dans HFSQLDans PostgreSQL
Analyse (fichiers, rubriques, liaisons)Schéma SQL : tables, colonnes, contraintes
Fichier de données (.fic, .ndx, .mmo)Table, ses index et ses colonnes de texte ou binaires
RubriqueColonne
Identifiant automatiquebigint GENERATED ALWAYS AS IDENTITY
Clé uniqueClé primaire ou contrainte UNIQUE
Clé avec doublonsIndex simple
Clé composéeIndex ou contrainte sur plusieurs colonnes
Liaison entre fichiersClé étrangère (REFERENCES)
Requêtes de l'éditeur (REQ_…)Requêtes SQL, vues
Procédures stockées et triggers HFSQL C/SFonctions PL/pgSQL et triggers, ou règles déplacées dans l'API

Correspondance des types

Type HFSQLType PostgreSQLPoint d'attention
Texte, chaîne Unicodevarchar(n) ou textEncodage ANSI à convertir en UTF-8, espaces de fin
Entier 1, 2, 4, 8 octetssmallint, integer, bigintPas d'entier non signé : prévoir le type supérieur
Réel 4 / 8 octetsreal, double precisionÀ éviter pour les montants
Monétaire, numériquenumeric(p, s)Précision et nombre de décimales à fixer
DatedateDates vides ou invalides à convertir en NULL
Heure, DateHeuretime, timestampFuseau horaire à décider
DuréeintervalUnité de stockage à vérifier
BooléenbooleanParfois stocké en entier ou en texte « O / N »
Mémo textetextEncodage, mise en forme RTF éventuelle
Mémo binaire, imagebytea ou fichiers externesVolume : stockage de fichiers parfois préférable

Exemple : un fichier HFSQL repris en PostgreSQL

Partons de deux fichiers d'une analyse WinDev : des clients et leurs commandes, reliés par une liaison.

Avant · analyse HFSQL (extrait)
Fichier CLIENT (vue simplifiée de l'analyse)
  IDClient       Identifiant automatique     clé unique
  CodeClient     Texte (20)                  clé unique
  Nom            Texte (100)                 clé avec doublons
  Ville          Texte (60)
  DateCréation   Date (AAAAMMJJ)
  Encours        Monétaire
  Remarques      Mémo texte

Fichier COMMANDE
  IDCommande     Identifiant automatique     clé unique
  IDClient       Entier 8 octets             clé avec doublons
  DateCommande   Date (AAAAMMJJ)             clé avec doublons
  MontantHT      Monétaire

Liaison : COMMANDE.IDClient → CLIENT.IDClient

Le schéma PostgreSQL reprend les mêmes informations, mais les rend explicites et contrôlées par la base : identifiants, unicité, liaison sous forme de clé étrangère, types adaptés aux montants et aux dates.

Après · schéma PostgreSQL
CREATE TABLE client (
  id_client      bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  code_client    varchar(20)  NOT NULL UNIQUE,
  nom            varchar(100) NOT NULL,
  ville          varchar(60),
  date_creation  date,
  encours        numeric(18,6) NOT NULL DEFAULT 0,
  remarques      text
);
CREATE INDEX client_nom_idx ON client (nom);

CREATE TABLE commande (
  id_commande    bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  id_client      bigint NOT NULL REFERENCES client (id_client),
  date_commande  date NOT NULL,
  montant_ht     numeric(18,6) NOT NULL
);
CREATE INDEX commande_client_date_idx ON commande (id_client, date_commande);

Le transfert ne se fait pas en une seule copie. Les données exportées sont chargées dans des tables d'import, puis reprises avec les conversions nécessaires. Le script est rejouable : on peut le lancer autant de fois que nécessaire sur des copies de la base avant la bascule réelle.

Après · script de reprise (SQL)
-- 1. Les données exportées de HFSQL arrivent dans une table d'import (tout en texte)
-- 2. Reprise avec conversion, en conservant les identifiants d'origine
INSERT INTO client (id_client, code_client, nom, ville, date_creation, encours, remarques)
OVERRIDING SYSTEM VALUE
SELECT id_client::bigint,
       trim(code_client),
       trim(nom),
       nullif(trim(ville), ''),
       CASE WHEN date_creation IN ('', '00000000') THEN NULL
            ELSE to_date(date_creation, 'YYYYMMDD') END,
       encours::numeric,
       nullif(remarques, '')
FROM import_client;

-- 3. Recaler le compteur pour les prochaines créations
SELECT setval(pg_get_serial_sequence('client', 'id_client'),
              (SELECT max(id_client) FROM client));

-- 4. Contrôle : commandes dont le client n'existe pas (liaison non vérifiée dans HFSQL)
SELECT i.id_commande, i.id_client
FROM import_commande i
LEFT JOIN client c ON c.id_client = i.id_client::bigint
WHERE c.id_client IS NULL;

La dernière requête illustre un point essentiel : HFSQL n'impose pas toujours l'intégrité des liaisons. Des commandes peuvent pointer vers un client supprimé depuis longtemps. PostgreSQL les refusera. Mieux vaut les découvrir pendant les essais que le jour de la bascule.

Les pièges d'une migration HFSQL

Les dates vides

Une date HFSQL peut être vide, à zéro ou même invalide selon l'historique de la saisie. PostgreSQL n'accepte que de vraies dates ou NULL. Chaque cas doit être converti, et l'application doit savoir gérer l'absence de valeur.

Les valeurs nulles

Selon les options de l'analyse, une rubrique HFSQL peut ne pas gérer la valeur nulle et stocker à la place une chaîne vide ou un zéro. Faut-il garder ce zéro ou le transformer en NULL ? La réponse dépend du sens métier de chaque champ : un encours à zéro n'est pas un encours inconnu.

Les doublons cachés et les liaisons orphelines

Une clé déclarée « avec doublons » alors qu'elle devrait être unique, une liaison non vérifiée : les années laissent des traces. Les contraintes de la nouvelle base les font apparaître. Nous les listons et décidons avec vous de leur traitement : correction, fusion ou archivage.

Les identifiants automatiques

Les identifiants existants doivent être conservés, car ils sont souvent référencés ailleurs (autres fichiers, documents, échanges avec d'autres logiciels). Après l'import, le compteur de la table doit être recalé, sinon la prochaine création échoue sur un identifiant déjà pris.

Les comparaisons de texte

Les clés HFSQL peuvent être paramétrées pour ignorer la casse ou les accents. Dans PostgreSQL, les comparaisons sont exactes par défaut. Pour retrouver le même comportement de recherche, il faut le prévoir : index sur une expression, collation adaptée ou colonne normalisée.

Le code qui lit la base

Changer la base sans adapter le code ne suffit pas. Les lectures enregistrement par enregistrement, les blocages et les filtres HFSQL doivent devenir des requêtes SQL et des transactions. C'est le sujet de nos pages WinDev vers C# / .NET et WebDev vers React.

Notre méthode de migration des données

  1. Analyse de la base. Lecture de l'analyse et des données réelles : volumétrie, types, liaisons, anomalies. Voir notre audit d'application WinDev.
  2. Conception du schéma cible. Tables, types, contraintes, index, en fonction des usages de l'application.
  3. Scripts de migration. Export, import et conversion, sous forme de scripts versionnés et rejouables.
  4. Répétitions et contrôles. Plusieurs passages sur des copies : comparaison des nombres de lignes, des totaux, des liaisons, et vérification par vos utilisateurs.
  5. Bascule. Gel de l'ancienne base, transfert final, contrôles, ouverture de la nouvelle.
  6. Suivi. Sauvegardes, supervision et accompagnement après la mise en production.

Vos données ne sont jamais ressaisies : elles sont transférées, contrôlées et rapprochées de l'ancienne base avant toute mise en production.

La migration de la base s'inscrit souvent dans un projet plus large : nouvelle application de bureau, site web ou application mobile. Pour une vue d'ensemble, consultez notre page migration et refonte d'applications WinDev.

Questions fréquentes

HFSQL vers PostgreSQL : vos questions.

Peut-on migrer HFSQL vers SQL Server ou MySQL plutôt que PostgreSQL ?

Oui. La démarche est la même : reprise du schéma, conversion des types, transfert et contrôle des données. Nous travaillons avec PostgreSQL, MySQL / MariaDB et SQL Server. PostgreSQL est souvent recommandé parce qu'il est open source, sans licence, et très complet.

Notre application WinDev peut-elle continuer à fonctionner après la migration de la base ?

C'est possible : WinDev sait accéder à des bases SQL externes. Mais le code qui s'appuie sur les spécificités de HFSQL (lecture enregistrement par enregistrement, blocages, filtres) doit alors être adapté. Le scénario est choisi pendant l'audit, selon que l'application est aussi migrée ou non.

Nos données sont-elles ressaisies ?

Non. Elles sont transférées par des scripts de migration, rejouables et vérifiés. Chaque passage est contrôlé : nombre de lignes, totaux, cohérence des liaisons. Les anomalies trouvées dans les données d'origine sont listées et traitées avec vous.

Faut-il arrêter l’application pendant la migration des données ?

Seulement le temps de la bascule finale. Les scripts sont d'abord rejoués sur des copies de la base, autant de fois que nécessaire. Le jour J, on fige l'ancienne base, on transfère, on contrôle, puis on ouvre la nouvelle.

Dossier migration

Les autres étapes de votre migration.

Contact

Parlons de votre
prochaine version.

Décrivez-nous votre projet en quelques mots. Nous revenons vers vous sous 48 h ouvrées.

Adresse55 rue Camille Pelletan
33150 Cenon