Pourquoi Go et PostgreSQL forment-ils la paire idéale ?
\n\nDans le monde du développement backend, Go (ou Golang) et PostgreSQL se sont imposés comme un tandem puissant pour créer des systèmes à haute charge et fiables. Go nous offre des performances incroyables, une simplicité et un excellent support de la concurrence, tandis que PostgreSQL est une base de données industrielle riche en fonctionnalités, fiable et extensible. En les combinant, vous obtenez une stack capable de supporter les charges d'une startup et les exigences d'un projet d'entreprise.
\n\nDans cet article, nous ne nous contenterons pas de survoler la syntaxe. Nous créerons un guide pratique complet : de l'installation du pilote à l'optimisation du pool de connexions et à la gestion des transactions. Vous apprendrez à éviter les erreurs typiques et à écrire du code Go efficace pour travailler avec PostgreSQL. C'est parti !
\n\nPour commencer : choisir le pilote et se connecter
\n\nLa première chose à faire est d'installer le pilote. Dans le monde Go, il y a deux principaux candidats :
\n- \n
- lib/pq — classique, simple, mais plus activement maintenu. \n
- pgx — moderne, rapide, activement développé, supporte plus de fonctionnalités PostgreSQL (par exemple, COPY, LISTEN/NOTIFY, tableaux). Je le recommande. \n
Installation de pgx :
\ngo get github.com/jackc/pgx/v5\n\nÉcrivons maintenant le code pour se connecter à la base de données. Créons un fichier main.go :
package main\n\nimport (\n "context"\n "fmt"\n "log"\n\n "github.com/jackc/pgx/v5/pgxpool"\n)\n\nfunc main() {\n // URL de connexion : utilisateur, mot de passe, hôte, port, nom de la BDD\n dsn := "postgres://myuser:mypassword@localhost:5432/mydb?sslmode=disable"\n\n // Création d'un pool de connexions\n pool, err := pgxpool.New(context.Background(), dsn)\n if err != nil {\n log.Fatalf("Impossible de créer le pool : %v", err)\n }\n defer pool.Close()\n\n // Vérification de la connexion\n err = pool.Ping(context.Background())\n if err != nil {\n log.Fatalf("Impossible de se connecter : %v", err)\n }\n\n fmt.Println("Connexion réussie à PostgreSQL !")\n}\n\nNotez que nous utilisons pgxpool, et non une simple connexion. Le pool de connexions est un must-have pour la production. Il permet de réutiliser les connexions, évitant ainsi les frais généraux de création et de fermeture.
Opérations CRUD : créer, lire, mettre à jour et supprimer
\n\nImplémentons maintenant les opérations classiques avec la table users. Supposons que nous ayons la structure :
type User struct {\n ID int\n Name string\n Age int\n}\n\n\nCréation de la table (Create)
\nIl est préférable d'effectuer les migrations avec des outils séparés, mais pour l'exemple, je montre comment exécuter du SQL brut :
\nfunc createTable(ctx context.Context, pool *pgxpool.Pool) error {\n query := `\n CREATE TABLE IF NOT EXISTS users (\n id SERIAL PRIMARY KEY,\n name TEXT NOT NULL,\n age INT NOT NULL\n );\n `\n _, err := pool.Exec(ctx, query)\n return err\n}\n\n\nAjout d'un enregistrement (Insert)
\nUtilisation de QueryRow pour retourner l'ID généré :
func createUser(ctx context.Context, pool *pgxpool.Pool, user *User) error {\n query := `INSERT INTO users (name, age) VALUES ($1, $2) RETURNING id`\n err := pool.QueryRow(ctx, query, user.Name, user.Age).Scan(&user.ID)\n return err\n}\n\n\nLecture d'un enregistrement (Select)
\nfunc getUserByID(ctx context.Context, pool *pgxpool.Pool, id int) (*User, error) {\n query := `SELECT id, name, age FROM users WHERE id = $1`\n user := &User{}\n err := pool.QueryRow(ctx, query, id).Scan(&user.ID, &user.Name, &user.Age)\n if err != nil {\n return nil, err\n }\n return user, nil\n}\n\n\n