Baie de serveurs illuminée illustrant une base de données PostgreSQL avec colonnes en majuscule

PostgreSQL – Filtrer sur une colonne dont le nom contient des majuscules

Sous PostgreSQL, une colonne avec une majuscule dans son nom ne se requête pas comme les autres. Sans précaution, la requête échoue avec une erreur peu intuitive. Cet article explique pourquoi PostgreSQL traite la majuscule différemment, comment écrire correctement la requête, et la bonne pratique pour éviter le problème à la racine.

Le comportement par défaut de PostgreSQL face à la majuscule

PostgreSQL convertit automatiquement en minuscules tous les identifiants non quotés. Cela inclut les noms de table, de colonne, et les alias. Une colonne déclarée comme queueName est donc référencée à l’écriture comme queuename si on ne met pas de guillemets.

Ce comportement fait partie du standard SQL. Il vise à rendre les requêtes insensibles à la casse pour les identifiants non protégés. C’est cohérent à grande échelle, mais ça surprend dès qu’un nom de colonne contient une majuscule.

Forcer la casse avec des doubles guillemets

Pour conserver la majuscule, il faut entourer le nom de la colonne avec des doubles guillemets. Sans eux, la requête échoue avec un message d’erreur :

-- Échoue avec : column "queuename" does not exist
SELECT * FROM _queue_items WHERE queueName = 'crawl-queue';

-- Fonctionne
SELECT * FROM _queue_items WHERE "queueName" = 'crawl-queue';

Les doubles guillemets indiquent à PostgreSQL de prendre l’identifiant tel quel, sans conversion de casse. C’est obligatoire dès qu’une majuscule est présente, même une seule.

En lecture comme en écriture

La règle s’applique partout où l’identifiant apparaît. Toutes ces formes nécessitent les doubles guillemets autour de queueName :

SELECT "queueName" FROM _queue_items;
UPDATE _queue_items SET "queueName" = 'foo';
INSERT INTO _queue_items ("queueName") VALUES ('foo');
SELECT * FROM _queue_items ORDER BY "queueName";

Oublier les guillemets sur une seule de ces commandes provoque la même erreur column does not exist. À noter, le double guillemet ne s’utilise jamais pour les valeurs, qui restent encadrées par des apostrophes.

Différence avec MySQL et SQL Server

MySQL utilise des backticks pour protéger les identifiants. Sa sensibilité à la casse dépend du système de fichiers : sensible sous Linux, insensible sous macOS et Windows par défaut. SQL Server accepte les crochets [queueName] et son comportement dépend de la collation.

Une migration depuis l’un de ces SGBD vers PostgreSQL est donc souvent l’occasion de découvrir le piège, parfois en production.

La bonne pratique : noms en minuscules

Pour ne plus avoir à se soucier des doubles guillemets, la convention la plus saine reste de nommer toutes les colonnes en minuscules avec des underscores : queue_name plutôt que queueName. C’est le style recommandé par la communauté PostgreSQL, et la plupart des ORM modernes (Doctrine, SQLAlchemy, ActiveRecord) le respectent par défaut.

Si tu hérites d’un schéma camelCase, l’option pragmatique est de toujours quoter, partout, dès qu’une majuscule est présente dans un nom d’identifiant.

Laisser un commentaire