Skip to Content

Le NoSQL dans le domaine géospatial, approche préliminaire en Python avec SimpleGeo.


python

Que signifie NoSQL ? Ce terme désigne une nouvelle catégorie de bases de données qui n'utilisent ni la notion relationnelle des SGBDR classiques, ni le langage SQL. NoSQL signifie en fait « Not Only SQL ».

Ces bases de données sont vraiment nées en 2009 (certaines existent depuis la fin des années 80) en réaction à la complexité des bases de données classiques et pour une utilisation dans l’« informatique dans les nuages » (cloud computing) du fait des nécessités de rapidité, de performance et des besoins en termes de charge et de volume de données (à titre d'exemple, toute la gestion du magasin en ligne Amazon est effectuée avec une base NoSQL).

Elles ont été créées et/ou sont actuellement utilisées par Google, Facebook, Ebay, Amazon, Twitter et autres pour leurs besoins propres. Elles ont des noms encore peu connus comme Google Big Table (Google), HBase (implémentation Open Source de la précédente), Amazon Simpledb (Amazon), Cassandra (Facebook, Open Source - Apache), CouchDB (Open Source - Apache), MongoDB (Open Source),  Redis (Open Source) ou Project Voldemort (Linkedin, Open Source) etc. Elles sont, dans leur grande majorité, Open Source.

Principes

L'explication la plus claire (pour moi) sur leurs principes et leur utilité est fournie dans « NoSQL : 5 minutes pour comprendre » (blog.neoxia.com/nosql-5-minutes-pour-comprendre/), site auquel je renvoie le lecteur.

Ces bases peuvent être classées en quatre grandes familles:

  • Clé-valeur (Key-value Stores):  les données sont représentées par un couple clé/valeur. La valeur peut être une simple chaîne de caractères ou un objet sérialisé (ex. Voldemort);
  • Orienté document (Document Oriented Databases) : les données ne sont pas stockées en termes de tables, de clés et de relations. Ici l'objet de base est la donnée elle-même, généralement au format JSON ou XML.  Elle peut donc contenir n'importe quel nombre de champs, et ce, quelle que soit sa longueur, et chaque champ peut stocker un nombre quelconque d'éléments. Le modèle permet, avec une seule clé, de récupérer un ensemble de données structurées de manière hiérarchique. La même opération dans le monde relationnel impliquerait plusieurs jointures (ex. Apache CouchDB, MongoDB, eXist pour les bases XML);
  • Orienté colonne (Columnar Databases) :  les données sont organisées en fonction des colonnes et non des lignes c'est-à-dire que les tables ont un nombre de colonnes dynamique (à la différence des tables dans les bases de données classiques). Chaque ligne a donc une clé unique, mais un nombre différent de colonnes, ce qui permet d'éviter les colonnes ayant des valeurs NULL (ex. Google Bigtable, Hbase)
  • Orienté graphe : modèle plus spécialisé, basé sur la théorie des graphes, avec des noeuds et des relations (arêtes) et les propriétés qui leur sont rattachées (la principale solution est Neo4J, que j'utilise, mais qui ne sera pas abordée dans la suite).

Cette absence de structure ou de typage ont un impact important sur le requêtage. En effet, toute l’intelligence portée auparavant par les requêtes SQL devra être portée par l’applicatif qui interroge la BD. Néanmoins, la communication avec la BD se résumera aux opérations PUT, GET et DELETE  ((blog.neoxia.com/nosql-5-minutes-pour-comprendre/)

Pour de plus amples renseignements, voir les sites  nosql-database.org/nosql.mypopescu.com/ et  blogs.neotechnology.com/emil/2009/11/nosql-scaling-to-size-and-scaling-to-complexity.html

Je constate simplement qu'il y a une grande variété de bases, relativement peu documentées, comme si tout d'un coup chacun voulait « sa » solution. Il me semble que le principe fondamental est celui de clé-valeur. Une base peut, en plus, être de type orientée document et/ou orientée colonne. Ainsi, Cassandra pourrait être décrite en terme de paires clé-valeur dont l'architecture est orientée colonne (oreilly.com/catalog/0636920010852).

Le nom choisi, NoSQL ( il aurait peut-être mieux fallu utiliser NotSQL), et l'abandon de l'aspect relationnel ont provoqué et provoquent toujours des débats passionnels, acharnés, voire plus, dans le monde des bases de données, mais, les aborder déborde du cadre de cet article, car je ne suis pas un spécialiste. Tout ce qui m'intéresse est d'en tester une dans le domaine géospatial.

Leur utilisation dans le domaine géospatial

Deux articles récents donnent quelques réponses :

Paul Ramsey passe en revue les avantages et désavantages de ces solutions et une des conclusions du deuxième article est :

One other point about NoSQL use, per Paul Ramsey, is that it's likely many developers will use NoSQL for spatial functions without really using a database. Instead, they will use a local or hosted service. He offers these examples: storing data in Google Fusion tables, using the SimpleGeo API, and using the spatial types in the Google App Engine. "These are all instances of using them [NoSQL databases] without using them. You see the limitations immediately in the kinds of queries you are able to do (not so many) but you reap the benefit of pushing the infrastructure responsibility off to someone else"

Une des solutions renseignées par ces auteurs est SimpleGeo.

SimpleGeo

SimpleGeo est une jeune startup américaine dont le but est de créer un « AppStore ou un iTunes » des données géolocalisées. Elle offre à cet effet une plateforme complète permettant de stocker ses données géolocalisées (« Storage Engine ») en offrant tous les outils nécessaires pour les exploiter sur les applications (« Context Engine »). Celles-ci sont surtout orientées vers le système Apple iOS4 de l'iPhone et de l'iPad.

Le principe est simple, chacun peut placer librement sur la plateforme ses données géolocalisées. Celles-ci peuvent ensuite être gardées pour soi, partagées librement ou vendues. Un « GeoMarketplace » est disponible à cet effet, permettant d’accéder aux nombreuses données des partenaires de SimpleGeo mais aussi de vendre ses propres données géographiques. L'entreprise se rémunère en fonction du nombre d'appels effectués par une application qui l'utilise : gratuit jusqu'à un million, 400 $ pour 2 millions d'appels et ainsi de suite.

Les informations géolocalisées de Twitter, Flickr, Brighkite, Wikipedia et autres sont déjà disponibles avec d'autres types de données comme la météorologie en temps réel.

À peine lancée,  SimpleGeo rencontre un grand succès aux États-Unis. Son discours commercial fait mouche : il suffit de quelques lignes de code pour qu'une entreprise soit en mesure d'intégrer un service de géolocalisation à une application tournant sur iPhone.

Ce qui m'intéresse ici, c'est qu'ils utilisent un système NoSQL (Cassandra) pour stocker les données et qu'il est possible de traiter les requêtes avec Python (entre autres langages,  JavaScript, PHP, Ruby, Objective - C etc.). 

SimpleGeo et Python

Les trois modules à installer sont sur le Python Package Index ou Pypi (pypi.python.org/pypi). Il s'agit de simplegeo-places, simplegeo-context (pour consulter les données) et simplegeo-shared (pour entrer les données). Ils sont écrits en pur Python et peuvent donc être installés avec easy_install ou pip sur toutes les plateformes (suivant les versions de Python, il y a des dépendances). Les versions expérimentales sont disponibles par git.

Il est aussi nécessaire de s'enregistrer sur le site de SimpleGeo (gratuit), ce qui vous donnera 2 clés d'utilisation pour vos scripts (OAUTHKEY et SECRET).

Une fois fait, le principe est simple. Le concept de base est la notion de feature. Une feature représente un objet spatial et toutes les informations qui lui sont associées (météo, entreprise, division administrative, etc..). Elle est composée d'un identifiant (SimpleGeo handle), d'une géométrie (geometry, points, polygones) et d'un ensemble de données supplémentaires (property) avec toutes les informations disponibles. Elle est codée au format GeoJSON.

simplegeo-context

Un premier exemple pour illustrer le propos (en me basant sur le tutoriel (simplegeo.com/docs/tutorials/python): je voudrai connaître ce qu'il y a aux alentours du point de coordonnées WGS84 37.770918,-122.494383 (tous les exemples sont fournis aux États-Unis, car il n'y a pas encore beaucoup de données géolocalisées pour la France ou la Belgique). Pour cela on utilise le module simplegeo-context. Le résultat des requêtes est retourné au format JSON.

requête

  1. import simplegeo.context as context
  2. # création d'un client
  3. client = context.Client('votre code OAUTHKEY', 'votre code SECRET')
  4. # interrogation de la base, qu'est ce qu'on trouve autour du point de coordonnées
  5. # 37.770918,-122.494383 en WGS84
  6. resultat = client.get_context(37.770918,-122.494383)
  7. # quel est la structure Python du résultat obtenu ?
  8. type(resultat)
  9. <type 'dict'>

Le résultat est une (très) longue chaîne au format JSON, non représentée ici, car son type Python est celui d'un dictionnaire qu'il est possible d'analyser plus facilement :

analyse

  1. #clés du dictionnaire
  2. print resultat.keys()
  3. ['query', 'demographics', 'features', 'timestamp']
  4. examen des valeurs
  5. print resultat.values()
  6. .... (beaucoup au format JSON
  7. #sérions le problème:
  8. # examen clé par clé
  9. print resultat.get('query')
  10. {'latitude': Decimal('37.770918'), 'longitude': Decimal('-122.494383')}
  11. # c'est la requête envoyée
  12. print resultat.get('demographics')
  13. {'metro_score': 10},...
  14. print resultat.get('timestamp')
  15. 1299359675.83
  16. # nombre de feature associées
  17. len(resultat.get('features'))
  18. 14
  19. # comme il y a beaucoup de features, examinons la première
  20. print resultat.get('features')[0]
  21. {'attribution': '(c) OpenStreetMap (http://openstreetmap.org/) and contributors',
  22. 'name': 'Golden Gate Park',
  23. 'license': 'http://creativecommons.org/licenses/by-sa/2.0/',
  24. 'bounds': [Decimal('-122.510828'), Decimal('37.764158'), Decimal('-122.453292'), Decimal('37.774642')], 'href': 'http://api.simplegeo.com/1.0/features/SG_7L9nQHjsporBjZUz8KVt5t_37.768985_-122.481775.json',
  25. 'abbr': None,
  26. 'handle': 'SG_7L9nQHjsporBjZUz8KVt5t_37.768985_-122.481775',
  27. 'classifiers': [{'category': 'Park',
  28. 'type': 'Public Place',
  29. 'subcategory': None}]}

Il y a donc plusieurs features aux alentours de ce point, mais comment une feature est-elle structurée ?

structure d'une feature

  1. type(resultat.get('features')[0])
  2. <type 'dict'>
  3. # c'est donc un dictionnaire dont on peut examiner le contenu
  4. print resultat.get('features')[0].get('handle')
  5. SG_7L9nQHjsporBjZUz8KVt5t_37.768985_-122.481775
  6. # c'est l'identifiant de la feature dans la base OpenGeo
  7. print resultat.get('features')[0].get('classifiers')
  8. [{'category': 'Park', 'type': 'Public Place', 'subcategory': None}]
  9. # c'est donc un Parc, avec comme limites (bounds)
  10. print resultat.get('features')[0].get('bounds'):
  11. [Decimal('-122.510828'), Decimal('37.764158'), Decimal('-122.453292'), Decimal('37.774642')]

Comment faire maintenant si je veux retrouver la géométrie de ce parc pour l'utiliser avec d'autres modules Python comme Shapely ou OGR ?

examen d'un des éléments

  1. # par requête directe à partir de son identifiant
  2. essai= client.get_feature('SG_7L9nQHjsporBjZUz8KVt5t_37.768985_-122.481775')
  3. type(essai)
  4. <type 'instance'>
  5. essai
  6. <simplegeo.shared.Feature instance at 0x10101d1b8>
  7. # ce n'est pas ce que l'on veut
  8. dir(essai)
  9. ['__doc__', '__init__', '__module__', 'coordinates', 'from_dict', 'from_json', 'geomtype', 'id', 'properties', 'strict_lon_validation', 'to_dict', 'to_json']
  10. # la documentation indique bien qu'il faut utiliser ici to_dict ou (to_json)
  11. essai= client.get_feature('SG_7L9nQHjsporBjZUz8KVt5t_37.768985_-122.481775').to_dict()
  12. type(essai)
  13. <type 'dict'>
  14. print essai.keys()
  15. ['geometry', 'type', 'id', 'properties']
  16. print essai.get('geometry')
  17. {'type': 'Polygon', 'coordinates': [[(Decimal('-122.5108283'), Decimal('37.7712413')), (Decimal('-122.4715533'), Decimal('37.7730133')), (Decimal('-122.468124'), Decimal('37.7731839')),...}
  18. print essai.get('properties')
  19. {'attribution': '(c) OpenStreetMap (http://openstreetmap.org/) and contributors', 'name': 'Golden Gate Park', 'license': 'http://creativecommons.org/licenses/by-sa/2.0/', 'private': False, 'href': 'http://api.simplegeo.com/1.0/features/SG_7L9nQHjsporBjZUz8KVt5t_37.768985_-122.481775.json', 'abbr': None, 'handle': 'SG_7L9nQHjsporBjZUz8KVt5t_37.768985_-122.481775', 'classifiers': [{'category': 'Park', 'type': 'Public Place', 'subcategory': None}]}

Le résultat est ici bien fourni au format GeoJSON standard (geometry etc.) que l'on pourra utiliser avec les autres modules. En pratique, il est possible de voir que les résultats obtenus par cette requête sont tous les polygones contenant le point recherché.

Ce résultat donne une première idée de la manière dont les données sont structurées dans la base SimpleGeo et des traitements nécessaires pour exploiter les résultats obtenus.

Mais je voudrai aller plus loin, sans traitement supplémentaire de ma part, pour trouver, par exemple, les hôtels autour de ce point (qui ne sont, en théorie, pas des polygones). Il faut alors utiliser simplegeo-places

simplegeo-places

La requête est alors la suivante :

requête hotels

  1. import simplegeo.places as places
  2. client = places.Client('votre code OAUTHKEY', 'votre code SECRET')
  3. # recherche des hotels autour de ce point
  4. resultats = client.search(37.788081, -122.402147, query='hotel')
  5. # type du resultat
  6. type(resultats)
  7. <type 'list'>
  8. print len(resultats)
  9. 25

Il y a donc 25 hôtels répertoriés aux alentours du point.

premier résultat

  1. print resultats[0].to_dict()
  2. {'geometry': {'type': 'Point', 'coordinates': (Decimal('-122.401619'), Decimal('37.788213'))},
  3. 'type': 'Feature',
  4. 'id': 'SG_47XBr8HAPbh7yFrsnpHURX_37.788269_122.401510@1293134755',
  5. 'properties': {'website': 'www.sfpalace.com',
  6. 'distance': Decimal('0.048664400718345879'),
  7. 'name': 'Palace Hotel',
  8. 'tags': ['operation', 'eating'], 'country': 'US', 'private': False, 'classifiers': [{'category': 'Travel', 'type': 'Entertainment', 'subcategory': 'Hotels & Motels'}], 'phone': '+1 415 512 1111', 'state': 'CA',
  9. 'href': 'http://api.simplegeo.com/1.0/features/SG_47XBr8HAPbh7yFrsnpHURX_37.788269_122.401510@1293134755.json',
  10. 'postcode': '94105',
  11. 'address': '2 New Montgomery St', 'owner': 'simplegeo', 'city': 'San Francisco'}}

Les résultats obtenus sont bien des points avec, dans les propriétés, le nom de l'hôtel, son site Web ou la distance du point à l'hôtel (l'unité de mesure n'est cependant pas spécifiée), et d'autres éléments. En utilisant son id (SG_47XBr8HAPbh7yFrsnpHURX_37.788269_-122.401510@1293134755), il est alors possible de le retrouver avec simple-context:

hôtel choisi

  1. client2=context.Client('votre code OAUTHKEY', 'votre code SECRET')
  2. essai=client.get_feature('SG_47XBr8HAPbh7yFrsnpHURX_37.788269_-122.401510@1293134755').to_dict()
  3. print essai
  4. {'geometry': {'type': 'Point', 'coordinates': (Decimal('-122.401619'), Decimal('37.788213'))},
  5. 'type': 'Feature',
  6. 'id': 'SG_47XBr8HAPbh7yFrsnpHURX_37.788269_122.401510@1293134755',
  7. 'properties': {'website': 'www.sfpalace.com', 'city': 'San Francisco',
  8. 'name': 'Palace Hotel',
  9. 'tags': ['operation', 'eating'], 'country': 'US', 'private': False, 'phone': '+1 415 512 1111', 'state': 'CA',
  10. 'href': 'http://api.simplegeo.com/1.0/features/SG_47XBr8HAPbh7yFrsnpHURX_37.788269_-122.401510@1293134755.json',
  11. 'postcode': '94105',
  12. 'address': '2 New Montgomery St', 'owner': 'simplegeo', 'classifiers': [{'category': 'Travel', 'type': 'Entertainment', 'subcategory': 'Hotels & Motels'}]}}

Ici, plus de distance (qui a donc été calculée par la requête), c'est l'identifiant brut de l'hôtel en question avec en href l'URL pour obtenir le résultat avec un navigateur (au format JSON)

api.simplegeo.com/1.0/features/SG_47XBr8HAPbh7yFrsnpHURX_37.788269_-122.401510@1293134755.json

Une feature de base est donc structurée de la manière suivante :

  1. un élément de type geometry;
  2. un élément de type d'objet
  3. un element id, qui est la clé pour retrouver l'objet (SimpleGeo handle);
  4. un élément properties, avec les propriétés associées

Le reste, distance, requête, etc. est effectué par la base et les outils SimpleGeo. Il y a aussi moyen de combiner les requêtes de diverses manières comme :

results = client.search(40.016983, -105.27753, query='coffee', category='restaurant')

Création d'une feature dans mon espace personnel (module simplegeo-shared)

Ces résultats nous indiquent maintenant comment créer une feature:

création d'une feature

  1. import simplegeo.shared, simplegeo.places
  2. from simplegeo.shared import Feature
  3. client = simplegeo.places.Client('votre code OAUTHKEY', 'votre code SECRET')
  4. properties = {"province":"","city":"Paris","name":"Tour Eiffel","country":"FR", "phone":"",
  5. "address":"7 Av Anatole France","postcode":"75007"}
  6. f = simplegeo.places.Feature((48.85940, 2.29416), properties=properties)
  7. client.add_feature(f)
  8. 'SG_41gn625SLWoHJOeoPYJ81b_48.859400_2.294160@1299419564'

qui nous indique l’identifiant de l'objet créé. On peut maintenant vérifier que l'objet existe bien dans la base SimpleGeo

contrôle

  1. # contrôle avec simplegeo.places
  2. print client.get_feature('SG_41gn625SLWoHJOeoPYJ81b_48.859400_2.294160@1299419564').to_dict()
  3. {'geometry': {'type': 'Point', 'coordinates': (Decimal('2.29416'), Decimal('48.8594'))},
  4. 'type': 'Feature',
  5. 'id':'SG_41gn625SLWoHJOeoPYJ81b_48.859400_2.294160@1299419564',
  6. 'properties': {'city': 'Paris', 'name': 'Tour Eiffel', 'country': 'FR', 'private': 'false', 'href': 'http://api.simplegeo.com/1.0/features/SG_41gn625SLWoHJOeoPYJ81b_48.859400_2.294160@1299419564.json', 'postcode': '75007', 'address': '7 Av Anatole France', 'owner': '6338', 'classifiers': []}}
  7.  
  8. # contrôle avec simplegeo.context
  9. client2 =simplegeo.context.Client(''votre code OAUTHKEY', 'votre code SECRET')
  10.  
  11. print client2.get_feature('SG_41gn625SLWoHJOeoPYJ81b_48.859400_2.294160@1299419564').to_dict()
  12. {'geometry': {'type': 'Point', 'coordinates': (Decimal('2.29416'), Decimal('48.8594'))},
  13. 'type': 'Feature',
  14. 'id': 'SG_41gn625SLWoHJOeoPYJ81b_48.859400_2.294160@1299419564',
  15. 'properties': {'city': 'Paris', 'name': 'Tour Eiffel', 'country': 'FR', 'private': 'false', 'href': 'http://api.simplegeo.com/1.0/features/SG_41gn625SLWoHJOeoPYJ81b_48.859400_2.294160@1299419564.json', 'postcode': '75007', 'address': '7 Av Anatole France', 'owner': '6338', 'classifiers': []}}

Et pour boucler la boucle avec la requête initiale

contrôle final avec la requête initiale

  1. import simplegeo.context as context
  2. client = context.Client('votre code OAUTHKEY', 'votre code SECRET')
  3. client.get_context(48.859400,2.294160)
  4. # etc.
  5. # le processus ayant été expliqué, je vais directement contrôler si mon objet est bien
  6. # dans la base SimpleGeo avec la requête initiale
  7. essai= client.get_feature('SG_41gn625SLWoHJOeoPYJ81b_48.859400_2.294160@1299419564').to_dict()
  8. print essai
  9. {'geometry': {'type': 'Point', 'coordinates': (Decimal('2.29416'), Decimal('48.8594'))},
  10. 'type': 'Feature',
  11. 'id':'SG_41gn625SLWoHJOeoPYJ81b_48.859400_2.294160@1299419564',
  12. 'properties': {'city': 'Paris', 'name': 'Tour Eiffel', 'country': 'FR', 'private': 'false', 'href': 'http://api.simplegeo.com/1.0/features/SG_41gn625SLWoHJOeoPYJ81b_48.859400_2.294160@1299419564.json', 'postcode': '75007', 'address': '7 Av Anatole France', 'owner': '6338', 'classifiers': []}}

Autre manière de travailler

Il y a aussi moyen de travailler de manière différente, plus classique pour les SIGistes. Il est en effet possible de créer classiquement une couche (Layer) et d'y ajouter des éléments (Records). La couche doit cependant être créée à partir de l'interface graphique du site SimpleGeo. Les Records peuvent être rentrés en Python:

création d'un record

  1. from simplegeo import Record
  2. r = Record('com.simplegeo.macouche', '4', 48.859400,2.294160)
  3. #nom de la couche,identifiant,latitude, longitude)
  4. client.add_record(r)

Ceci permet d'importer directement les données depuis des shapefiles ou des fichiers CSV dans la base SimpleGeo (avec des scripts Python) mais seuls les points sont supportés pour l'instant (SimpleGeo travaille sur l'importation des polygones):

Comment exploiter les résultats en ligne (Web Mapping) ?

Rien de plus simple, puisque SimpleGeo a développé sa propre librairie JavaScript Polymaps (Open Source) à cet effet :

developers.simplegeo.com/blog/2011/01/14/how-to-display-simplegeo-places-on-a-map/

Conclusions

Et voilà, que dire d'une base NoSQL ?

Sans vouloir entrer dans les controverses, je constate, en pratique, que SimpleGeo marche très bien. Rapide, sans nécessité de module spécialisé en Python (le module JSON est en standard depuis la version 2.6 et pour les versions antérieures il existe le module SimpleJSON), la base utilisée par SimpleGeo ne demande que des traitements simples pour être exploitée (contrairement aux bases de données relationnelles classiques). La seule chose qui me gêne un peu est la relative « verbosité » du format JSON-GeoJSON.  On constate aussi que la plupart des traitements doivent être faits par l'application qui reçoit les données.

Il ne faut pas oublier que cette technologie est encore jeune et doit évoluer. Elle n'est certainement pas adaptée à tous les cas rencontrés et il est difficile, pour un non-spécialiste, de s'y retrouver dans la jungle des solutions... Il ne faut donc pas nécessairement sauter dedans à pieds joints... Pour l'instant, je la vois plutôt comme un outil complémentaire. On peut très bien utiliser l'un et l'autre et non, exclusivement, l'un ou l'autre.

L'aspect économique joue aussi, ainsi le fondateur de SimpleGeo:

Joe Stump of SimpleGeo concedes it's possible to use SQL/relational databases to do what NoSQL databases can. For him, the choice to use NoSQL is about money.

'I guess what I'm saying is that my decision to use NoSQL, and I'm guessing others' decisions to do so, has less to do with the fact that we can't squeeze a few thousand writes a second out of MySQL and more to do with management and cost overhead. NoSQL solutions allow us to serve absurd amounts of data for a really, really low price.'

www.directionsmag.com/articles/nosql-databases-what-geospatial-users-need-to-know/164635

De manière plus générale, pour ceux que ça intéresse en Python, il existe  2010.rmll.info/L-acces-aux-bases-NoSql-en-python.html, qui a pour but de présenter les principales bases NoSQL  accessibles en Python, avec un tutoriel d’installation, une modélisation de schéma et un exemple d’application accédant aux données. nosql.mypopescu.com/post/276069660/nosql-libraries, déjà cité,  indique pour chaque base de données les modules/librairies Python, Perl, C, NET#, Ruby, etc. disponibles.

Et enfin, pour vraiment débuter, il y a deux sympathiques petits modules Python,

  • y_serial, qui permet de s'initier aux bases NoSQL de type clé-valeur avec..., SQLite;
  • littletable, qui fait de même avec les bases de type orienté colonne.

Tous les traitements ont été effectués sur Mac OS X avec Python 2.6.1.


Site officiel : SimpleGeo
Site officiel : GeoJSON
Site officiel : PolyMaps
Site officiel : Cassandra (Apache)
Site officiel : y-serial (module Python)
Site officiel : littletable (module Python)
Autres Liens : NoSQL (Wikipedia)
Autres Liens : Cassandra (Wikipedia)
Autres Liens : Base de données orientée colonnes (Wikipedia)
Autres Liens : Python pour les Sigistes: comment installer un module externe (geojson, shapely ou gdal/ogr, par exemple) ?


Creative Commons License
licence Creative Commons Paternité-Pas d'Utilisation Commerciale-Partage des Conditions Initiales à l'Identique Commerciale 2.0 France

Commentaires

sympathiques modules Python

y_serial, qui permet de s'initier aux bases NoSQL de type clé-valeur:
https://github.com/rsvp/yserial

Et pour un manuel d'instruction:
http://nbviewer.ipython.org/urls/git.io/yserial-HOWTO.ipynb

Félicitations

Super article bien expliqué et documenté.
C'est un vrai plaisir de lire tes rubriques !

Arnaud

Poster un nouveau commentaire

Le contenu de ce champ sera maintenu privé et ne sera pas affiché publiquement.