Saturday, February 8, 2014

Il database delle località - usare SQLite3

SQLite3 è un piccolo gioiello. Nato come database SQL, rispetto a MySQL o Oracledb, si presenta molto più leggero: ha un footprint, cioè una memoria totale occupata di meno di 400K (ricordiamo che un dischetto floppy convenzionale ha 1440 Kbyte di memoria disponibile) e riesce, teoricamente, a pilotare un database di 2 Terabyte (molto teorico, secondo me). Nonostante le piccole dimensioni e l'uso di file locali anzichè di un server, ha una elevata compliance con lo standard di linguaggio SQL e si presta all'uso professionale, come ho avuto modo di verificare personalmente.
Essendo public domain , è diventato lo standard de facto dei sistemi embedded, lo troviamo su Android, IOS, i comuni browser lo utilizzano per i propri setting, Adobe, Apple, Dropbox e un'infinità di altre imprese. Se siete curiosi consultate questa pagina. In Python è già presente nelle librerie base ed è facilmente evocabile, come vi mostrero' in questo post e nei successivi.
SQLite versione 3 si puo' usare in vari modi, da linea di comando, da software specializzato (SQLiteman è quello che preferisco) o attraverso una libreria di linguaggio. Nel caso di Python, proviamo a indovinare, si fa l'import della libreria con
import sqlite3
in testa al codice.
Già in linea di comando è possibile gestire agevolmente database anche voluminosi. Ho lavorato senza problemi, utilizzando solo qualche script, database con 2 milioni di record e quasi 1.3 Gigabytes di memoria occupata.
Se volete un buon tutorial su SQLite3 o in generale su SQL, il linguaggio comune dei database, vi consiglio questo sito: zetcode.com, che contiene una sezione dedicata a SQLite in linea di comando e una per l'uso con la libreria di Python. Altre cose altrettanto utili le trovate con Google quasi immediatamente.
Per il nostro piccolo progetto un database è indispensabile. Python fornisce diverse funzionalità per la gestione di dati memorizzati su disco, da pickle a shelve, che consentono la gestione in memoria di dati complessi come istanze di classe eccetera, ma per una database di tipo convenzionale preferisco usare sqlite3.
A noi serve un database delle località nel mondo, che riporti almeno il paese, la località, latitudine e longitudine ed eventualmente un dato di popolazione, giusto per filtrare e concentrare l'attenzione su località popolate. Ho trovato molto adatto allo scopo geonames che contiene diversi file adatti allo scopo, forniti in formato testuale ma facilmente convertibili.
Il primo è allCountries.zip, che contiene i record di diversi milioni di località, il secondo è admin1CodesASCII.txt, che fornisce una tabella con le principali suddivisioni regionali dei paesi del mondo. (per l'Italia il nome delle regioni). Ulteriori suddivisioni amministrative sono presenti nel file admin2Codes.txt, che ho ritenuto non necessario
Il file allCountries.zip pesa 236 Megabytes zippato, decompresso supera 1.1 Giga. Potete tentare di leggerlo con un editor di testo, ma preparatevi ad aspettare parecchio prima che venga caricato, ammesso che il vostro computer regga una dimensione del genere. Proveremo piuttosto a scriver un piccolo script (programma) in Python, che faccia il lavoro di estrazione per nostro conto e trasferisca i risultati automaticamente in un file csv (comma separated values, che SQLite importa senza difficoltà.
Poichè blogspot non consente di allegare file che non siano immagini, vi passo lo script che potete divertirvi a lanciare sul vostro editor Python preferito. Lo script presume che il file allCountries.txt sia nella stessa directory in cui lo script viene lanciato. Al termine sarà disponibile il file allNews.csv che conterrà i dati essenziali in formato di linee di testo, separati da un punto e virgola per ogni linea:

  1. nome della località in formato Unicode 
  2. nome della località in carattere ASCII
  3. latitudine
  4. longitudine
  5. paese (sigla di 2 caratteri)
  6. codice della principale suddivisione amministrativa (regione)
  7. popolazione
  8. timezone
<hr />


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#1/usr/bin/env python
file_in = open('allCountries.txt','r')
file_out = open('allNews.csv','w')
elenco=file_in.readlines()
file_in.close()
count = 1
for i in elenco:
    a=i.split('\t')
    if int(a[16])>0:
        file_out.write(a[1]+";"+a[2]+";"+a[4]+";"+a[5]+";"+a[6]+";"+a[10]+";"+a[16]+";"+a[17]+"\n")
        count+=1
        if count % 100000 == 0:
            print count,
file_out.close()
file_in.close()

Nel prossimo post useremo il database così ottenuto per visualizzare i dati con una interfaccia grafica

No comments:

Post a Comment

How to create a virtual linux machine with qemu under Debian or Ubuntu with near native graphics performance

It's been a long time since my latest post. I know, I'm lazy. But every now and then I like to publish something that other people c...