Ce blog a pour but de diffuser les informations liées aux applications et données libre et open source, plus connus sous le terme de GFOSS. Esprit critique, annonce de nouveautés, compte rendu de salon et bien d'autres choses encore, voilà ce que vous y trouverez. RSS Souscrire via RSS

[GDAL-OGR] Mode ajout dans une base de données PostGreSQL

Il y a quelques temps je devais importer des données au format EDIGEO dans une base PostGreSQL/PostGIS existante. J’avais plusieurs fichiers THF à importer par conséquent je devais créer la table puis importer les fichiers les nus après les autres. Après lecture attentive de la documentation puis poser quelques questions sur la liste gdal, voici la méthode ainsi que les petites astuces qui font la différence.

Visualisation du problème

Puisque la table n’existe pas au premier fichier THF, il faut que la commande ogr2ogr s’en occupe puis, dans un deuxième temps, il faut que cette même commande ajoute les données. La doc est assez clair là dessus : il faut lancer deux commandes l’une après l’autre (en fait seules quelques options sont différentes) :

ogr2ogr -gt 65536 -f "PostgreSQL" "PG:dbname=test  host='localhost'" -lco "GEOMETRY_NAME=the_geom" -lco "SCHEMA=test" -lco "OVERWRITE=YES" -nln EDIGEO_parcelle  E0001.THF PARCELLE_id

Cette commande s’exécute sans problème. Les options utilisées ici sont les suivantes :

  • -gt 65536 : permet de grouper les géométries par groupe de 65 536 géométries avant de les commiter. Cela évite de commiter les géométries les unes après les autres. La valeur utilisée est celle préconiser par la documentation.
  • -lco « SCHEMA=test » : importer les données dans un schéma particulier.
  • -lco « GEOMETRY_NAME=the_geom » : totalement inutile mais j’aime bien avoir une cohérence dans mes noms de colonnes géométriques.
  • -lco « OVERWRITE=YES » : obligatoire quand on fait plusieurs essaie ou quand la table existe déjà pour cause d’import déjà réalisé. Cette option indique que la table sera écrasée (détruite puis recrée).
  • -nln EDIGEO_parcelle : donner un nom différent à la table que l’on va créer. Notez le mélange de majuscules et de minuscule, nous en reparlerons plus tard.

La deuxième commande que j’ai testé pour ajouter les données à une table existante esty celle-ci :

ogr2ogr -append -update -gt 65536 -f "PostgreSQL" "PG:dbname=test host='localhost'" -lco "GEOMETRY_NAME=the_geom" -lco "SCHEMA=test" -nln EDIGEO_parcelle  E0002.THF PARCELLE_id

Et là, ca marche beaucoup moins bien car je reçois ce message :

ERROR 1: Layer test.edigeo_parcelle already exists, CreateLayer failed.
Use the layer creation option OVERWRITE=YES to replace it.
ERROR 1: Terminating translation prematurely after failed
translation of layer PARCELLE_id (use -skipfailures to skip errors)

Et les logs de PostgreSQL montrent que cela ne provient pas de la base de données :

Postgresql log file shows:
2013-03-06 15:35:44 CET LOG:  could not receive data from client: Connection
reset by peer
2013-03-06 15:35:44 CET LOG:  unexpected EOF on client connection

Compréhension du problème et solution

En regardant les logs d’un peu plus près, voici ce que l’on y trouve :

  1. le nom de la table créée est test.edigeo_parcelle, ce qui est incorrecte en regard de la commande que j’ai lancé (le nom de la table aurait dû être EDIGEO_parcelle.
  2. une commande est réalisée lors du mode ajout et celle-ci ne cherche pas la table dans le schéma test mais dans le schéma public.

Ces deux problèmes peuvent être réglés de plusieurs manières différentes.

La solution « fainéant »

Résumons la par « Ah ben ca marche pas avec des majuscules et dans un schéma autre que le schéma public, tant pis ». La solution ici est de mettre le nom de la table en minuscule (bonne pratique) et celle-ci dans le schéma public (pas bien !).

La solution dite de « contournement »

Elle s’approche de la première car elle n’utilise pas les options nécessaires (et ajoutées pour) ce cas de figure et elle ne sert qu’au deuxième problème (celui du schéma) :

ogr2ogr -append -update -gt 65536 -f "PostgreSQL" "PG:dbname=test host='localhost'" -nln test.edigeo_parcelle  E0002.THF PARCELLE_id

Notez ces modifications :

  1. -lco « SCHEMA=test » et -lco « GEOMETRY_NAME=the_geom » ont été supprimés car inutile. Les options -lco ne sont pas utilisées en mode append ou update (ben oui le c de lco est pour « création », logique !).
  2. le nom de la table dans l’option -nln a été modifié en test.edigeo_parcele : tout en minuscule et ajout du schéma

La solution qui utilise les bonnes options

Comprenons bien les problèmes. Un premier problème vient du fait que le nom de la table que nous souhaitons créer contient des majuscules qui sont transformés en minuscule. Le deuxième problème vient du fait que nous utilisons une option de création pour définir le schéma dans lequel insérer des données alors que nous somme en mode append/update.

Nettoyage des noms de couches/table, colonne

Le pilote PostgreSQL dans GDAL/OGR contient un système de nettoyage des valeurs données lors de la création d’une couche. Cette option se nomme « LAUNDER » et est définie dans la page du pilote : http://gdal.gloobe.org/ogr/formats/pg.html (en français) :

Elle peut être définie à *YES* pour forcer les nouveaux champs créés sur cette couche à avoir les noms de champs « nettoyés » dans une forme compatible avec PostgreSQL. Cela convertie la valeur en minuscule ainsi que certains caractères spéciaux comme « – » et « # » en « _ ». Si la valeur *NO* est utilisée les noms exacts seront préservés. La valeur par défaut est *YES*. Si activé le nom de la table (couche) sera également nettoyé.

Si l’on souhaite garder nos majuscules il faut définir cette option à « NO ».

Définition du schéma en mode append/update

Lorsque nous somme en mode append ou update, nous ne somme pas en mode de création. C’est peu de le dire, c’est évident, mais au final on n’en saisit pas toujours les conséquences : les options de création ne nous serons d’aucune utilité ! Heureusement il y a une possibilité : le paramètre « active_schema » dans la chaîne de connexion. Notre commande devient alors :

ogr2ogr -append -update -gt 65536 -f "PostgreSQL" "PG:dbname=test host='localhost' active_schema=test" -nln edigeo_parcelle  E0002.THF PARCELLE_id

Merci à Even Rouault pour son aide sur la liste.


Commentaires fermés sur [GDAL-OGR] Mode ajout dans une base de données PostGreSQL
Posté le : 21 Mar 2013
Tags: , , ,
Posté dans Applications, Données |

- Faire un don - Contact - Mentions légales -