GoVueKit

SQLite ou PostgreSQL : une base de code, deux moteurs, une variable d'environnement

20 mai 2026

La plupart des boilerplates choisissent une base de données et la scellent dans le code. GoVueKit supporte les deux, sélectionnées par DB_DRIVER, et le même SQL tourne sur l'une comme sur l'autre. Cet article explique comment, ce que ça coûte, et — la partie qui compte vraiment — quand SQLite est un choix de production légitime plutôt qu'un jouet.

Pourquoi s'embêter à supporter les deux

Le développement. SQLite veut dire que make dev fonctionne sur un portable neuf sans service à installer, sans conteneur à démarrer, sans identifiants à inventer. Le fichier est créé et migré au premier lancement.

La petite production. Un produit mono-serveur avec quelques milliers d'utilisateurs et un trafic surtout en lecture tourne parfaitement sur SQLite, avec des sauvegardes qui sont une copie de fichier.

Des tests qui veulent dire quelque chose. La CI fait tourner toute la suite Go deux fois, une par moteur. Les bugs qui n'apparaissent que sur un moteur sont trouvés par la machine, pas par un client.

L'optionalité. Si vous grandissez jusqu'aux écritures concurrentes, vous changez une variable au lieu de réécrire des requêtes.

Comment la portabilité est réellement obtenue

Quatre règles, moins contraignantes qu'elles n'en ont l'air.

1. Des types portables uniquement. TEXT pour les identifiants (des UUID générés en Go, jamais SERIAL), TIMESTAMP pour le temps, BOOLEAN, INTEGER. Pas de type de colonne propre à un moteur, pas de JSONB, pas de tableaux.

2. RETURNING est autorisé. Les deux moteurs le supportent, ce qui supprime la danse du dernier identifiant inséré et garde les insertions à un aller-retour.

3. Une seule génération de code. sqlc génère contre le dialecte PostgreSQL avec des placeholders $1 — et le pilote SQLite en pur Go (modernc.org/sqlite) accepte $N nativement. Un seul jeu de types Go générés sert donc les deux moteurs au lieu de deux packages divergents.

4. Pas de CGO. modernc.org/sqlite est SQLite traduit en Go. C'est ce qui permet à go build de compiler en croisé un binaire statique sans chaîne d'outils C, et c'est la raison pour laquelle l'histoire du « un seul fichier à déployer » tient sur les deux moteurs.

Ce à quoi vous renoncez : les opérateurs JSONB, la recherche plein texte de PostgreSQL, les colonnes tableau, les vues matérialisées, LISTEN/NOTIFY. Si la fonctionnalité centrale de votre produit a besoin de l'un d'eux, prenez PostgreSQL dès le premier jour — le kit y tourne nativement et vous cessez simplement de vous soucier du chemin SQLite.

Quand SQLite suffit en production

La limite de SQLite, ce sont les écritures concurrentes : un écrivain à la fois, en série. En pratique, en mode WAL, ça supporte bien plus que ce que les gens supposent — des milliers d'écritures par seconde sur un matériel correct, parce que chaque écriture est courte.

C'est un bon choix quand :

Passez à PostgreSQL quand :

Le résumé honnête : SQLite va plus loin que sa réputation, et au moment où il vous faut deux serveurs applicatifs, plus rien de tout ça ne compte — le fichier ne se partage pas, et vous migrez.

Passer de l'un à l'autre

Le schéma est le même ; seules les données ont à voyager. Le chemin est un export et un chargement, pendant une fenêtre de maintenance :

  1. Arrêtez l'application.
  2. Exportez chaque table depuis SQLite (CSV ou instructions INSERT).
  3. Démarrez avec DB_DRIVER=postgres et AUTO_MIGRATE=true pour que goose crée le schéma.
  4. Chargez les données, puis vérifiez le nombre de lignes par table et relancez la suite de tests contre la nouvelle base.
  5. Redémarrez l'application.

Il n'y a aucune dérive de schéma générée par un ORM à réconcilier, parce que les migrations sont les mêmes fichiers. Faites-le tôt — déplacer 50 000 lignes est une soirée, 50 millions un projet.

Les règles à garder si vous éditez le SQL

La portabilité est une discipline, pas une bibliothèque. Trois habitudes la maintiennent :

Ce dernier point est le vrai compromis. La portabilité vous coûte les fonctionnalités avancées des deux moteurs ; en échange, le développement n'a aucune dépendance et la production a une porte de sortie.

La question qui dérange

Supporter deux moteurs vaut-il le coup pour votre produit ? Si vous savez que vous tournerez sur PostgreSQL, vous pouvez supprimer le chemin SQLite et utiliser JSONB librement. Le kit ne vous en empêche pas — c'est votre code source.

Ce que vous perdriez, c'est la propriété qui rend le premier lancement gratuit : cloner le dépôt, démarrer le serveur, et la base est un fichier qui n'existait pas une seconde plus tôt. C'est aussi ce qui rend la suite de tests assez rapide pour tourner à chaque sauvegarde.

Gardez les deux tant que vous êtes petit. Abandonnez-en un délibérément, avec une ligne dans DECISIONS.md, si votre produit dépasse le compromis.

Voyez comment la couche de données s'assemble, ou lisez le guide de déploiement pour la mise en production sur l'un ou l'autre moteur.