Le backend PostgreSQL dans Forge (forge-mvc-postgres)¶
Ce document explique ce que fait l'opt-in forge-mvc-postgres, ce qu'il expose, et comment on s'en sert.
forge-mvc-postgres est un backend de base de données pour Forge, au-dessus de psycopg (v3), pour faire fonctionner la couche BDD du cœur sur un serveur PostgreSQL.
Le cœur de Forge est agnostique BDD (ADR-054) : il découvre le backend installé par un entry point et n'en utilise qu'un seul par projet.
Statut Alpha
La logique de dialecte et la traduction des paramètres sont testées unitairement, mais l'intégration serveur et le provisioning par db:init restent à valider/câbler.
À ce stade, créez la base et le rôle à la main, puis utilisez db:apply / migration:*.
1. Rôle du module¶
Le cœur génère le SQL et pilote les commandes BDD ; un backend les fait parler à un vrai serveur.
forge-mvc-postgres fournit ce backend pour PostgreSQL : un adaptateur de connexion psycopg conforme aux attentes du cœur, et un dialecte SQL PostgreSQL.
Particularité technique : Forge génère des paramètres ? ; l'adaptateur les traduit en %s (format psycopg) à l'exécution.
2. Vue d'ensemble rapide¶
| Élément | Valeur |
|---|---|
| Paquet | forge-mvc-postgres |
| Module | forge_mvc_postgres |
| Catégorie | Bases de données (ADR-055) |
| Statut | Alpha (dialecte testé, intégration à valider) |
| Couche | backend BDD opt-in exclusif (un seul par projet) |
| Dépend de | forge-mvc, psycopg (v3), un serveur PostgreSQL |
| Découverte | entry point forge_mvc.db_backend nommé postgres |
| Sélection | automatique si seul installé ; sinon DB_BACKEND=postgres |
| Paramètres | ? traduits en %s à l'exécution |
| Identité | BIGSERIAL |
| Provisioning CLI | pas encore câblé : création base + rôle manuelle |
| Décision d'architecture | ADR-054 |
| Installation | pip install --pre forge-mvc-postgres |
3. Schémas UML¶
Les deux schémas suivants montrent deux vues complémentaires du backend.
Le diagramme de classe montre l'adaptateur et le dialecte.
Le diagramme de séquence montre la traduction des paramètres à l'exécution.
3.1 Diagramme de classe¶
Le diagramme de classe montre que le backend enveloppe psycopg pour répondre au contrat du cœur, en traduisant les paramètres.
classDiagram
direction LR
class DatabaseBackend {
<<protocol, cœur>>
+name
+dialect
+get_connection()
}
class PostgreSQLBackend {
+name = "postgres"
+requires_provisioning = true
+get_connection() connexion
}
class translate {
<<module>>
+translate_placeholders(sql) str
}
class PostgreSQLDialect {
+BIGSERIAL
+CREATE INDEX séparés
+guillemets doubles
}
class psycopg {
<<pilote>>
}
PostgreSQLBackend ..|> DatabaseBackend : implémente
PostgreSQLBackend --> psycopg : connexion
PostgreSQLBackend --> translate : ? -> %s
PostgreSQLBackend --> PostgreSQLDialect : dialecte
À retenir :
- le backend enveloppe
psycopg(curseur lignes-dict, lastrowid vialastval()) ; - les paramètres
?de Forge sont traduits en%s; - le dialecte gère
BIGSERIALet lesCREATE INDEXséparés ; psycopgest importé paresseusement (l'usage du dialecte ne le requiert pas).
3.2 Diagramme de séquence¶
Le diagramme de séquence montre une requête traduite à l'exécution.
sequenceDiagram
participant Core as core.database
participant Backend as forge-mvc-postgres
participant Tr as translate_placeholders
participant PG as PostgreSQL (psycopg)
Core->>Backend: execute("... WHERE id = ?", (42,))
Backend->>Tr: traduit ? en %s
Tr-->>Backend: "... WHERE id = %s"
Backend->>PG: execute(sql traduit, (42,))
PG-->>Backend: résultat
Backend-->>Core: lignes (dict)
À retenir :
- la traduction
?vers%sest transparente pour le cœur ; - les littéraux chaîne sont préservés à la traduction ;
lastrowidest obtenu viaSELECT lastval();- le SQL généré reste celui de Forge, juste adapté au format psycopg.
4. Ce que fournit le backend¶
| Élément | Rôle |
|---|---|
PostgreSQLBackend |
implémente le contrat DatabaseBackend |
Adaptateur psycopg |
curseur lignes-dict (dict_row), lastrowid via lastval() |
translate_placeholders |
traduit ? en %s |
PostgreSQLDialect |
BIGSERIAL, CREATE INDEX séparés, guillemets doubles, information_schema |
| Entry point | forge_mvc.db_backend = postgres |
5. Contextes d'utilisation¶
| Besoin | Élément |
|---|---|
| Utiliser PostgreSQL | installer forge-mvc-postgres + un serveur PostgreSQL |
| Forcer ce backend | DB_BACKEND=postgres |
| Créer base et rôle | à la main (Alpha) : createdb, CREATE ROLE |
| Appliquer le schéma | forge db:apply (sur une base existante) |
| Faire évoluer le schéma | forge migration:* |
6. Exemple d'utilisation (Alpha)¶
# 1. Préparer base et rôle à la main (provisioning CLI non câblé)
createdb mon_projet
psql -c "CREATE ROLE mon_projet LOGIN PASSWORD '...';"
psql -c "GRANT ALL ON DATABASE mon_projet TO mon_projet;"
# 2. Installer le backend et configurer env/dev (DB_HOST, DB_NAME, DB_APP_*)
pip install --pre forge-mvc-postgres
# 3. Appliquer le schéma
forge db:apply
Le code applicatif utilise core.database.db, comme avec tout autre backend.
Aide-mémoire
En Alpha :
- créez la base et le rôle à la main ;
db:apply/migration:*fonctionnent sur la base existante ;?est traduit en%sautomatiquement.
7. Statut Alpha et limites¶
Le dialecte (types, DDL) et la traduction des paramètres sont testés unitairement. L'intégration sur un vrai serveur reste à valider côté projet.
Le provisioning par db:init n'est pas encore câblé pour PostgreSQL : créez la base et le rôle manuellement en attendant.
À valider sur un serveur
Tester réellement PostgreSQL demande un serveur (local ou conteneur Docker).
db:init peut signaler que le provisioning n'est pas pris en charge pour ce backend : c'est attendu (Alpha).
Dialecte PostgreSQL
BIGSERIAL pour l'identité, CREATE INDEX séparés, guillemets doubles, introspection via information_schema.
Indépendance du cœur
Le cœur de Forge ne dépend pas de forge-mvc-postgres : il le découvre par entry point (ADR-054).
Voir aussi¶
- Progression PostgreSQL : apprendre le backend pas à pas.
- ADR-054 : cœur agnostique BDD.