Retour au blog
mars 2018·3 min de lectureTraduit par IA
Langue:DeutschEnglishFrançaisÖsterreichischKlingonian Version originale: Deutsch

Les obstacles d'OpenGeoDB

#geodb#opengeodb#plz#postleitzahlen#strassen#strassenverzeichnis

Réflexions préalables

Pour un projet en cours, j'avais besoin d'une liste de tous les codes postaux d'Allemagne avec les noms de villes correspondants. Certes, « plus il y a de données, mieux c'est » ;-) mais c'étaient au moins les exigences minimales. À la fin, on devait obtenir un champ de saisie avec autocomplétion nous affichant le code postal et la localité correspondante. La première tâche est donc de se procurer les données, et M. Google m'a conduit au projet très prometteur OpenGeoDB. On y trouve vraiment toutes les données imaginables sur une localité, que l'on pourrait souhaiter :

  • Clé officielle de commune
  • Nom de tri
  • Nom
  • Coordonnées WGS84
  • Latitude
  • Longitude
  • Regroupement administratif
  • Nom de tri d'un regroupement administratif
  • Code postal
  • Indicatif téléphonique
  • Nombre d'habitants
  • Nombre d'habitants approximatif (wtf !)
  • Nombre d'habitants exact
  • Superficie
  • Plaque d'immatriculation
  • Type (d'après l'entrée : local/spécialisé), niveau
  • Marquage comme invalide

Il est donc devenu assez vite clair que j'y trouverais les données dont j'avais besoin. J'ai donc commencé par télécharger les données sous forme de dump SQL. Curieusement, il y a ici 3 fichiers :

  • opengeodb-begin.sql : un fichier plutôt petit qui ne fait que créer les tables.
  • DE.sql : les données réelles. 60 Mo d'instructions insert ouf
  • opengeodb-end.sql : la finition. Les titres sont créés et les index générés.

La structure de base

Nous commençons donc par opengeodb-begin.sql pour créer la structure de base. C'est là que nous rencontrons l'obstacle, alias l'erreur numéro 1.

[FEHLER in Abfrage 3] You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'TYPE=InnoDB CHARACTER SET utf8' at line 10

La base de données ne connaît donc pas TYPE=InnoDB. Dommage. Cela tient au fait que le dump a été créé avec une version antérieure à MySQL 4. Depuis MySQL 4, la base n'écoute plus TYPE mais ENGINE. Solution : ouvrir le dump dans l'éditeur de votre choix et remplacer « TYPE=InnoDB » par « ENGINE=InnoDB ». Réimporter le dump et se réjouir de l'import réussi.

Le jeu de données

On continue avec le jeu de données. Il suffit d'importer le fichier DE.sql (valable bien sûr uniquement pour l'Allemagne ; les Autrichiens prennent AT.sql, les Suisses CH.sql, etc.) et d'attendre… d'attendre… que les quelque 600 000 enregistrements soient importés… puis de recevoir le message d'erreur disant que 0 n'est pas une date (… vraiment ?)

Incorrect date value: '0' for column 'valid_since' at row 1

L'attente était donc vaine. Youpi. Il faut vider à nouveau la table et réfléchir à ce qui a mal tourné. En principe, j'étais parti du principe que les données d'OpenGeoDB sont en soi correctes et que le problème venait de ma configuration MySQL, qui n'admet tout simplement pas de 0. Peut-être que ma base ne devrait pas être aussi stricte et admettre exceptionnellement, ou de façon générale, un 0 comme date. Le manuel MySQL m'a mené à la variable strict_mode, que l'on peut lire avec un rapide SHOW VARIABLES LIKE 'sql_mode', et qui m'a renvoyé

ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

Il fallait donc retirer « NO_ZERO_IN_DATE,NO_ZERO_DATE », et comme cela devait être persistant, j'ai configuré le my.cnf, qui se trouvait chez moi sous /usr/local/etc/my.cnf. Il fallait y ajouter sql_mode = ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION (= la sortie de SHOW VARIABLES sans les valeurs NO_ZERO_IN_DATE et NO_ZERO_DATE) et redémarrer le serveur avec un aimable brew services restart mysql. Ensuite, vérifier de nouveau l'état avec « SHOW VARIABLES LIKE 'sql_mode' » pour voir si tout a fonctionné. Il est temps d'un nouvel essai : importer DE.SQL et attendre. Cette fois, tout devrait marcher :)

Finition

L'étape 3 est l'import de opengeodb-end.sql, qui effectue la « finition » : insertion des titres et création des index. Tout s'est déroulé sans erreur ici ouf. Les données sont maintenant importées et peuvent être traitées. Qui ne veut les modifications que temporairement peut les obtenir avec set global sql_mode='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'.

TL;DR

  1. Télécharger les jeux de données depuis opengeodb.giswiki.org/wiki/OpenGeoDB_Downloads : opengeodb-begin.sql, opengeodb-end.sql, DE.sql
  2. Ouvrir opengeodb-begin.sql dans l'éditeur et remplacer TYPE=InnoDB par ENGINE=InnoDB
  3. Importer opengeodb-begin.sql
  4. Exécuter sql_mode='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'
  5. Importer DE.sql
  6. Importer opengeodb-end.sql
Plus récentSnippets PHP