slony | replicare db postgresql (postgis)
Pubblicato da flaviorigolon in db-ing & geodb-ing il 25 maggio 2012
Ho provato a buttarmi (finalmente dico io) su Slony. Si tratta di un sistema per replicare uno o più database da un server postgresql su un altro o piu’ server (anche remoti).
Ho fatto un piccolo test (per ora) cercando di replicare il db spaziale (con estensione postgis) della carta tecnica regionale numerica su un altro server.
Su entrambi i server gira Debian stable (ad oggi “squeeze”) ed hanno rispettivamente gli IP: 192.168.1.71 e 100.0.4.231.
Creiamo il database (vuoto) sul server slave con il comando:
$ su
# su postgres
# psql
=# CREATE DATABASE ctr_new_slave OWNER sit template=template_gis;
e lo strutturiamo come “ctr_new” (db master):
$ pg_dump -s -U postgres -h localhost ctr_new | psql -U postgres -h 100.0.4.71 ctr_new_slave
Quest’ultimo comando è stato impartito dal server master.
Installare slony via apt-get:
# apt-get install slony1-2-bin postgresql-8.4-slony1-2
Il database (già presente) deve avere abilitato il linguaggio procedurale plpgsql. Essendo un db creato mediante un “template_gis” che già incorpora questo linguaggio non ho dovuto fare niente. In caso di nuovo db ricordarsi invece di abilitarlo con:
(come utente postgres) # createlang plpgsql nome_db
Una prerogativa per il funzionamento di slony è che ogni tabella del db abbia una chiave primaria (notare che possono essere replicate anche solo alcune tabelle specificandole nel file di configurazione che vedremo dopo).
Configurazione degli script altperl
Ci sono diversi modi per configurare e manovrare slony: in questo esempio useremo gli script altperl (si tratta di script in perl appunto).
ci spostiamo della directory “/etc/slony/” e copiamo al suo interno il file di configurazione di esempio che si trova in “/usr/share/doc/slony1-2-bin/examples/slon_tools.conf-sample.gz” (dopo averlo decompresso e averne fatto una copia chiamata slon_tools.conf)
(come root):
# cd /etc/slony
# cp /usr/share/doc/slony1-2-bin/examples/slon_tools.conf .
modifichiamo il file con nano:
# nano slon_tools.conf
riporto il file:
======================================================
# $Id: slon_tools.conf-sample,v 1.8.2.4 2009-08-17 22:21:38 devrim Exp $
# Author: Christopher Browne
# Copyright 2004-2009 Afilias Canada
# Revised extensively by Steve Simms
# Keeping the following three lines for backwards compatibility in
# case this gets incorporated into a 1.0.6 release.
#
# TODO: The scripts should check for an environment variable
# containing the location of a configuration file. That would
# simplify this configuration file and allow Slony-I tools to still work
# in situations where it doesn’t exist.
#
if ($ENV{“SLONYNODES”}) {
require $ENV{“SLONYNODES”};
} else {
# The name of the replication cluster. This will be used to
# create a schema named _$CLUSTER_NAME in the database which will
# contain Slony-related data.
$CLUSTER_NAME = ‘replication’;
# The directory where Slony should record log messages. This
# directory will need to be writable by the user that invokes
# Slony.
$LOGDIR = ‘/var/log/slony1′;
# SYNC check interval (slon -s option)
# $SYNC_CHECK_INTERVAL = 1000;
# Which node is the default master for all sets?
$MASTERNODE = 1;
# Which debugging level to use? [0-4]
$DEBUGLEVEL = 2;
# Include add_node lines for each node in the cluster. Be sure to
# use host names that will resolve properly on all nodes
# (i.e. only use ‘localhost’ if all nodes are on the same host).
# Also, note that the user must be a superuser account.
add_node(node => 1,
host => ’192.168.1.71′,
dbname => ‘ctr_new’,
port => 5432,
user => ‘postgres’,
password => ”);
add_node(node => 2,
host => ’100.0.4.71′,
dbname => ‘ctr_new_slave’,
port => 5432,
user => ‘postgres’,
password => ”);
}
# The $SLONY_SETS variable contains information about all of the sets
# in your cluster.
$SLONY_SETS = {
# A unique name for the set
“set1″ => {
# The set_id, also unique
”set_id” => 1,
# Uncomment the following line to change the origin
# (a.k.a. master) for the set. The default is $MASTERNODE.
#
# “origin” => 1,
# If this is set to 1, table and sequence names will be folded to lower-case
# to match the way that PostgreSQL handles unquoted names.
# For example, CREATE TABLE ACCOUNT(…) actually turns into CREATE TABLE account(…);
# unless you put quotes around the table name
# Slony always quotes object names, so you may get a mis-match between the table-name
# as PostgreSQL understands it, and as Slony represents it.
# default value is 0
#
# foldCase => 0,
# The first ID to use for tables and sequences that are added
# to the replication cluster. This must be unique across the
# cluster.
#
# TODO: This should be determined automatically, which can be
# done fairly easily in most cases using psql. create_set
# should derive it, and give an option to override it with a
# specific value.
”table_id” => 1,
”sequence_id” => 1,
# This array contains a list of tables that already have
# primary keys.
“pkeyedtables” => [
'public.aree_ter',
'public.astefer',
'public.asteflu',
'public.astevia',
'public.cam_fabb',
'public.curve',
'public.discont',
'public.ele_div',
'public.err_l',
'public.fabbr_l',
'public.fabbric',
'public.ferrovie',
'public.geometry_columns',
'public.idrogr_a',
'public.idrograf',
'public.infras_a',
'public.infrastr',
'public.inquadra',
'public.lim_amm',
'public.limamm_a',
'public.nodofer',
'public.nodoflu',
'public.nodovia',
'public.opere',
'public.punti_q',
'public.sim_disc',
'public.sim_elem',
'public.sim_fabb',
'public.sim_idro',
'public.sim_infr',
'public.sim_oper',
'public.sim_vege',
'public.sim_viab',
'public.spatial_ref_sys',
'public.testi',
'public.veget_a',
'public.vegetaz',
'public.viab_a',
'public.viabilit',
],
# For tables that have unique not null keys, but no primary
# key, enter their names and indexes here.
#”keyedtables” => {
# ‘table3′ => ‘index_on_table3′,
# ‘table4′ => ‘index_on_table4′,
#},
# If a table does not have a suitable key or set of keys that
# can act as a primary key, Slony can add one.
#
# Note: The Slony development team does not recomment this
# approach — you should create your own primary keys instead.
# “serialtables” => ["table5"],
# Sequences that need to be replicated should be entered here.
#”sequences” => ['sequence1',
# 'sequence2',
# ],
},
};
# Keeping the following three lines for backwards compatibility in
# case this gets incorporated into a 1.0.6 release.
#
# TODO: The scripts should check for an environment variable
# containing the location of a configuration file. That would
# simplify this configuration file and allow Slony tools to still work
# in situations where it doesn’t exist.
#
if ($ENV{“SLONYSET”}) {
require $ENV{“SLONYSET”};
}
# Please do not add or change anything below this point.
1;
======================================================
Ho modificato il file di esempio togliendo le parti relative a “keyedtables” e “serialtables” e inserendo i nomi delle tabelle (con relativo schema) da replicare. Inoltre ho lasciato inalterate le impostazioni per “$CLUSTER_NAME = ‘replication’;” e “$LOGDIR = ‘/var/log/slony1′;”. La prima identificherà con un prefisso un nuovo schema nei due db e l’altra indica dove salvare i file di log.
Configurazione di slonik
Una volta editato il file di configurazione possiamo usalro per generare gli script da passare al modulo “slonik” (siamo sempre all’interno della cirectory “/etc/slony/”).
# slonik_init_cluster > initcluster
# slonik_create set 1 > createset
# slonik_subscribe_set 1 2 > subscribeset
In questo modo vengono creati 3 file ognuno dei quali contiene il codice per impostare un cluster e farlo partire.
Accendere i motori
Ora possiamo fare partire il tutto:
# slonik < initcluster
che dovrebbe produrre un output simile a questo:
<stdin>:10: Set up replication nodes
<stdin>:13: Next: configure paths for each node/origin
<stdin>:16: Replication nodes prepared
<stdin>:17: Please start a slon replication daemon for each node
Può succedere che compaiano dei messaggi di errore (nel mio caso avevo scritto alcuni nomi di tabelle sbagliate nel file slon_tools.conf). In questo caso correggere il file suddetto, rimuovere i tre script creati con “# rm initcluster createset subscribset“, poi entrare dei due db “ctr_new” e “ctr_new_slave” e rimuovere lo schema “_replication” con “=# DROP SCHEDA -replication CASCADE;“. Infine ripartire con la creazione degli script di configurazione.
Avviamo slon sul server 1:
# slon_start 1
Invoke slon for node 1 – /usr/bin/slon -p /var/run/slony1/node1.pid -s 1000 -d2 replication ‘host=192.168.1.71 dbname=ctr_new user=postgres port=5432′ >>/var/log/slony1/node1-ctr_new.log 2>&1 </dev/null &
Slon successfully started for cluster replication, node node1
PID [5815]
Start the watchdog process as well…
e avviamo slon sul server 2:
# slon_start 2
Invoke slon for node 2 – /usr/bin/slon -p /var/run/slony1/node2.pid -s 1000 -d2 replication ‘host=100.0.4.71 dbname=ctr_new_slave user=postgres port=5432′ >>/var/log/slony1/node2-ctr_new_slave.log 2>&1 </dev/null &
Slon successfully started for cluster replication, node node2
PID [5879]
Start the watchdog process as well…
Ora creiamo cluster e subscribe
# slony < createset
<stdin>:16: Subscription set 1 created
<stdin>:17: Adding tables to the subscription set
<stdin>:21: Add primary keyed table public.aree_ter
<stdin>:25: Add primary keyed table public.astefer
<stdin>:29: Add primary keyed table public.asteflu
<stdin>:33: Add primary keyed table public.astevia
<stdin>:37: Add primary keyed table public.cam_fabb
<stdin>:41: Add primary keyed table public.curve
<stdin>:45: Add primary keyed table public.discont
<stdin>:49: Add primary keyed table public.ele_div
<stdin>:53: Add primary keyed table public.err_l
<stdin>:57: Add primary keyed table public.fabbr_l
<stdin>:61: Add primary keyed table public.fabbric
<stdin>:65: Add primary keyed table public.ferrovie
<stdin>:69: Add primary keyed table public.geometry_columns
<stdin>:73: Add primary keyed table public.idrogr_a
<stdin>:77: Add primary keyed table public.idrograf
<stdin>:81: Add primary keyed table public.infras_a
<stdin>:85: Add primary keyed table public.infrastr
<stdin>:89: Add primary keyed table public.inquadra
<stdin>:93: Add primary keyed table public.lim_amm
<stdin>:97: Add primary keyed table public.limamm_a
<stdin>:101: Add primary keyed table public.nodofer
<stdin>:105: Add primary keyed table public.nodoflu
<stdin>:109: Add primary keyed table public.nodovia
<stdin>:113: Add primary keyed table public.opere
<stdin>:117: Add primary keyed table public.punti_q
<stdin>:121: Add primary keyed table public.sim_disc
<stdin>:125: Add primary keyed table public.sim_elem
<stdin>:129: Add primary keyed table public.sim_fabb
<stdin>:133: Add primary keyed table public.sim_idro
<stdin>:137: Add primary keyed table public.sim_infr
<stdin>:141: Add primary keyed table public.sim_oper
<stdin>:145: Add primary keyed table public.sim_vege
<stdin>:149: Add primary keyed table public.sim_viab
<stdin>:153: Add primary keyed table public.spatial_ref_sys
<stdin>:157: Add primary keyed table public.testi
<stdin>:161: Add primary keyed table public.veget_a
<stdin>:165: Add primary keyed table public.vegetaz
<stdin>:169: Add primary keyed table public.viab_a
<stdin>:173: Add primary keyed table public.viabilit
<stdin>:176: Adding sequences to the subscription set
<stdin>:177: All tables added
Ed infine:
# slony < subscribeset
<stdin>:4: NOTICE: subscribe set: omit_copy=f
<stdin>:4: NOTICE: subscribe set: omit_copy=f
CONTEXT: SQL statement “SELECT “_replication”.subscribeSet_int( $1 , $2 , $3 , $4 , $5 )”
funzione PL/pgSQL “subscribeset” linea 68 a PERFORM
<stdin>:10: Subscribed nodes to set 1
Tutto è partito: se andiamo a vedere i file di log in “/var/log/slony/” vediamo cio’ che accade.
Per fare un test ho provato a caricare la stessa tabella (spaziale) in QGIS (la stessa tabella del db master e dello slave). Modificando (aggiunto un elemento geometrico) la tabella e facendo un refresh si notano quasi istantaneamenete i cambiamenti replicati anche nel db slave!
Ogni commento è benvenuto.
qualche tips su django
Pubblicato da flaviorigolon in db-ing & geodb-ing, linuxing il 24 maggio 2012
Rimozione django
Per rimuovere django installato da sorgenti (nel caso si voglia installare una versione piu’ recente, per esempio) basta trovare la directory “django” e cancellarla. Per trovarla impartire il comando:
sit@debian:~$ python -c “import sys; sys.path = sys.path[1:]; import django; print(django.__path__)”
che nel mio caso restituisce:
['/usr/lib/pymodules/python2.6/django']
MD_PYTHON ERROR in django
Dopo un blocco inaspettato del server (durante un processo di rsync) il gestionale django installato riportava il seguente errore:
MOD_PYTHON ERROR
…………..
…………..
Import Error: Could not import settings ‘my_app.settings’ (Is it on sys.psth? Does it have syntax error?): No module named myapp.settings
Dopo avere cercato in rete ho trovato che la causa di questo messaggio potrebbe essere:
- file di configurazione di apache errato;
- sys.path sbagliato;
- permessi non corretti su cartelle e files del progetto (permessi che inibiscono all’utente www-data di leggere i file di settings);
- bug nel codice django.
Prima di procedere ho provato a replicare l’aplicativo sul portatile (compreso db postgresql colllegato) e tutto funzionava a modino (NB: stesso SO Debian stable).
Quindi ho confrotato il file di configurazione di apache (/etc/apache2/apache2.conf”) e sono identici; quindi il problema non sta li;
ho confrontato il sys.path delle due macchine: per farlo ho lanciato una shell python, poi:
>>> import os, sys
>>> print sys.path
ed i risultati sono identici: quindi anche la seconda ipotesi e’ scartata.
Anticipo che il bug nel codice django e’ da escludere a priori visto che sul portatile gira senza problemi. Rimangono da verificare i permessi sulle cartelle del progetto.
Infatti confrontando i listati di “ls -l” sulle due macchine si nota che la directory “/home/user/” ha dei permessi differenti (nel server e’ inibita la lettura a tutti. Molto probabilmente durnate l’operazione di rsync lanciato da root ha modificato i diritti di accesso durante; il blocco del server causato da un down temporaneo della rete ha messo in lock anche le directory interessate). Cambiando questa impostazione con:
$ chmod 751 -R /home/user/
tutto e’ andato a posto
Da Postgresql 8.3 e Postgis 1.3.3 a Posgresql 8.4.11 e Postgis1.5.1 su Debian stable
Pubblicato da flaviorigolon in db-ing & geodb-ing, linuxing, mapping il 24 maggio 2012
Con questo post volevo tenere traccia della procedura di aggiornamento e migrazione dati da Postgresql 8.3 e Postgis 1.3.3 a Posgresql 8.4.11 e Postgis1.5.1.
Ho seguito questa utilissima pagina wiki
Sul nostro server “girano” attualmente Postgresql 8.3 e Postgis 1.3.3.
1- Facciamo dapprima il backup dei database presenti (il comando va lanciato per ogni db presente nel cluster).
$ PGUSER=postgres pg_dump -Fc nome_db > /percorso/alla/dir/di/dump/nome_db.dmp
NB: pg_dump con l’opzione -Fc crea un archivio compresso (un tar compresso con gzip, ovvero un tar.gz).
Nel caso si trattasse di db non spaziale e’ sufficiente dare:
$ PGUSER=postgres pg_dump -c nome_db > /percorso/alla/dir/di/dump/nome_db.sql
2- Stoppiamo Postgresql-8.3 (come root):
# /etc/init.d/postgesql stop 8.3
3- Installiamo Postgresql-8.4 e Postgis-1.5
# aptitude install postgresql-8.4 postgresql-8.4-postgis
A questo punto (non ricordo purtroppo tutte le fasi che ho percorso) al comando di stop de nuovo postgresql-8-4 compariva un errore. Ho provato a reinstallarlo ma a questo punto ottengo:
# Error: move_conffile: required configuration file /var/lib/postgresql/8.4/main/postgresql.conf does not exists.
Decido allora di reinstallare tutto ma succede il fattaccio. Non si riesce piu’ a lanciare postgresql-8-3. Il messaggio d’errore diceva che non esiste piu’ la directory “/var/lib/postgresql/8.3/main” panic…..praticamente mi e’ sparito tutto il cluster di postgresql-8.3, fumato!
Ok, pero’ i backup li ho e decido di fare un purge profondo prima di ripartire. Cerco tutti i pacchetti relativi a Postgresql.
# dpkg -l | grep postg
e rimuovo tutto con:
# aptitude purge postgresql-8.3 postgresq-8.4 postgresql-client-8.3 postgresql-client-8.4 postgresql-client-common postgresql-common postgresql
Rimuovo anche tutte le directory di sistema:
# rm -r /etc/postgresql/
# rm -r /etc/postgresql-common/
# rm -r /var/lib/postgresql/
poi togliamo manualmente l’utente “postgres” dal file “/etc/passwd” (mediante “# nano /etc/passwd” e modificando il file eliminado la riga di interesse).
Quindi reinstallo tutto con:
# aptitude install postgresql-8.4 postgresql-8.4-postgis (che si tira dietro anche tutte le dipendenze del caso)
A questo punto possiamo recuperare i dump fatti. Per fare questo ci viene in aiuto uno script in perl che si installa con postgis-1.5 (new_postgis_restore.pl).
Prima si devono ricreare i database vuoti (con lo stesso nome di quello di partenza). Essendo tutti db spaziali creiamo dapprima un template spaziale che chiamiamo “template_gis” e lo useremo poi per creare ogni db.
Come utente postgres creiamo anche gli utenti dei db stessi:
$ su
# su postgres
(come utente postgres) # psql template1; (si entra in un db qualsiasi per creare gli utenti)
=# CREATE USER nome_utente WITH PASSWORD ‘secret’ CREATEDB CREATEUSER;
Creo il nuovo database che diventaera’ il template (sempre come utente postgres):
=# CREATE DATABASE template_gis template=template0;
Usciamo dal db (<CTRL>d) e (sempre come utente postgres) importiamo in esso le funzioni spaziali:
# psql -f /usr/share/postgresql/8.4/contrib/postgis-1.5/postgis.sql -d template_gis
poi
# psql -d template_gis -f /usr/share/postgresql/8.4/contrib/postgis-1.5/spatial_ref_sys.sql
A questo punto rientriamo in template1:
# psql template1;
e facciamo in modo che il nuovo db sia un template usabile in futuro:
# UPDATE pg_database SET datistemplate=’t’ WHERE datname=’template_gis’;
ok, ora possiamo creare tutti i nostri db in base a questo template.
# CREATE DATABASE nome_db template=template_gis OWNER nome_utente; (questo va fattoper ogni db)
Quindi popoliamo i db con lo script perl citato prima (come utente normale):
$ /usr/share/postgresql/8.4/utils/new_postgis_restore.pl /percorso/alla/dir/di/dump/nome_db.dmp | psql nome_db
Vedremo scorrere sul terminale una serie di istruzioni (il db si sta popolando). Fatto.
Alla fine (nel mio caso) ricordarsi di modificare i file “/etc/postgresql/8.4/main/postgresql.conf” e “/etc/postgresql/8.4/main/pg_hba.conf”.
Per il primo decommentare la riga relativa a “listen_addresses” e inserire l’asterisco al posto di “localhost” come riportato:
#——————————————————————————
# CONNECTIONS AND AUTHENTICATION
#——————————————————————————
# – Connection Settings -
listen_addresses = ‘*’ # what IP address(es) to listen on;
………………
Per il secondo (nella parte finale del file):
# Database administrative login by UNIX sockets
local all postgres ident
# TYPE DATABASE USER CIDR-ADDRESS METHOD
# “local” is for Unix domain socket connections only
local all all trust
# IPv4 local connections:
host all all 127.0.0.1/32 trust
host all all 0.0.0.0/0 trust
# IPv6 local connections:
host all all ::1/128 trust
altrimenti non sono consentiti connessioni da altri client (nel primo file) e l’esecuzione di pg_dumpall (nel secondo file)
linux | qualche tip, qualche trick…
Pubblicato da flaviorigolon in linuxing, scripting il 5 aprile 2012
rename
comando per rinominare uno o piu’ file; in particolare mi e’ tornato utile per rinominare una serie di immagini che presentavano alcune lettere maiuscuole, altre minuscole. Per riportare tutto a minuscolo:
$ rename ‘y/A-Z/a-z/’ *
In questo modo tutti i file presenti nella dir corrente vengono trattati e rinominati in lowercase.
primo script in python | da gradi sessagesimali a gradi decimali
Pubblicato da flaviorigolon in linuxing, mapping, scripting il 19 marzo 2012
Pubblico il mio primo timido script “operativo ” in python. E’ frutto di un misto tra studio e tentativi vari spulciando tutorial in rete, un piccolo pocket libro e il famoso “diveintopython”
.
Il lavoro che presento è l’evoluzione del piccolo script che, attendendo gli input dell’utente, converte i gradi, primi e secondi di un angolo in formato sessagesimale (una coordinata geografica in lat-lon per esempio) in formaro decimale (molto utile per l’elaborazione in molti programmi GIS).
In questo secondo step invece viene letto un file in formato .CSV contenente gli angoli nel formato gradi, primi, secondi (con la virgola come separatore) e viene generato un nuovo file (.CSV) con gli angoli convertiti nella forma decomale. Ecco lo script:
========================
from __future__ import division
angoli= open( “/home/sit/python/angoli.txt”, “r” ) # apre in lettura il file che contiene gli angoli da elaborare
angoli_trasformati=open(“/home/sit/python/angoli_trasformati.txt”, “w”) # genera un nuovo file che conterra’ i risultati
for angolo in angoli:
try:
g, p, s = angolo.strip().split( “,” ) # crea una tupla eliminando eventuali spazi tra valori e separandoli (i valori) con una virgola “,”
res = float(g), float(p), float(s), (float(g)+(((float(s)/60)+float(p))/60)) # calcola il valore dell’angolo in formato decimale
print res
print>>angoli_trasformati, res # restituisce l’output sul file creato in precedenza
except ValueError:
pass
angoli.close() # chiude lo stat sul file aperto
angoli_trasformati.close() # chiude lo stat sul file generato
========================
ogni commento e’ benvenuto
il primo “hello world” in python
Pubblicato da flaviorigolon in linuxing, scripting il 8 marzo 2012
A distanza di qualche mese mi sono riavvicinato alla programmazione (una espressione “grossa” per me) tentando di rifare un esperimento: convertire un angolo dal formato gradi primi secondi a decimale.
Riporto il codice python:
gradi = input(‘scrivi i gradi: ‘)
primi = input(‘scrivi i primi: ‘)
secondi = input(‘scrivi i secondi: ‘)
print “l’angolo in formato decimale e’”,float(gradi)+(((float(secondi)/60)+float(primi))/60)
[per evitare di dichiarare ogni input come float() si puo' importare il modulo divisione; ecco il codice modificato:
from __future__ import division
gradi = input('scrivi i gradi: ')
primi = input('scrivi i primi: ')
secondi = input('scrivi i secondi: ')
print "l'angolo in formato decimale e'",gradi+(((secondi/60)+primi)/60)
il risultato non cambia]
salvandolo in un file che potermmo chiamare dms2dd.py ed eseguendolo otterremo quanto richiesto:
$ python2.7 dms2dd.py
scrivi i gradi: 45
scrivi i primi: 5
scrivi i secondi: 5
l’angolo in formato decimale e’ 45.0847222222
postgresql | qualche tips, qualche tricks
Pubblicato da flaviorigolon in db-ing & geodb-ing il 13 gennaio 2012
Posto alcuni comandi pgsql che ho avuto modo di usare di recente dovendo maneggiare i formati date di Postgresql. Li metto cosi’ in ordine sparso e premetto che fanno riferimento ad un database usato per la gestione dei consumi energetici di impianti di illuminazione; pertanto alcuni commenti (personali) fanno riferimento a questo tipo di lavoro. Tuttavia vanno benissimo per qualsiasi altro db.
Sia data una tabella “tbl01″ che contiene un campo “anno” come stringa, “data01″, “data02″, “data03″, ”data04″ campi in formato date, “consumo_anno” come integer :
# comando SELECT per recuperare il valore del campo “anno” sul quale faremo le nostre operazioni:
mydb=# SELECT anno FROM tbl01 WHERE id=4;
anno
——
2010
(1 row)
Come si puo’ vedere si tratta di un campo varchar di 4 caratteri.
# comando SELECT che converte in numero (attualmente in formato testo) il campo “anno” della tabella “tbl01″:
mydb=# SELECT to_number(anno, ’9999′) FROM tbl01 WHERE id=4;
to_number
———–
2010
(1 row)
# comando SELECT per convertire in numero il campo “anno” e togliere 1:
mydb=# SELECT to_number(anno, ’9999′)-1 FROM tbl01;
?column?
———-
2009
2009
2008
2009
(4 rows)
# comando per convertire in data nel formato YYYYMMDD il valore del campo “anno”:
mydb=# SELECT to_date(anno,’YYYYMMDD’) FROM tbl01 WHERE id=4;
to_date
————
2010-01-01
(1 row)
# calcolo del 31 dicembre dell’anno precedente a quello in oggetto (con riferimento al campo “anno”):
mydb=# SELECT to_date(anno,’YYYYMMDD’)-1 FROM tbl01;
?column?
————
2009-12-31
2009-12-31
2008-12-31
2009-12-31
(4 rows)
# comando per calcolare la differenza tra una data chiamata “data1″ (inizio anno) e il 31 dicembre dell’anno precedente (giorni in eccesso inizio anno): siano data0=2008-12-29, data1=2009-01-12, data2=2009-12-31, data3=2009-12-31.
mydb=# SELECT data1-(to_date(anno,’YYYYMMDD’)-1) FROM tbl01 WHERE id=4;
?column?
———-
12
(1 row)
# comando per calcolare la differenza tra il 31 dicembre dell’anno precedente e la prima data “data0″ (giorni in difetto inizio anno):
mydb=# SELECT (to_date(anno,’YYYYMMDD’)-1)-data0 FROM tbl01 WHERE id=4;
?column?
———-
2
(1 row)
# comando per calcolare la differenza tra “data3″ e il 31 dicembre dell’anno in corso (giorni in eccesso fine anno):
mydb=# SELECT data3-(to_date(anno,’YYYYMMDD’)+364) FROM tbl01 WHERE id=4;
?column?
———-
0
(1 row)
# comando per calcolare la differenza tra il 31 dicembre dell’anno in corso e la “data2″ (giorni in difetto fine anno):
mydb=# SELECT (to_date(anno,’YYYYMMDD’)+364)-data2 FROM tbl01 WHERE id=4;
?column?
———-
0
(1 row)
===========================================================================
Supponiamo di avere due tabelle in relazione 1 a molti (tabella “a” e tabella “b”) con campo di collegamento (“id” della tabella “a” si collega a a_id della tabella “b”). Se vogliamo recuperare valori da entrambe le tabelle:
mydb=# SELECT a.campo1, b.campo2 FROM a,b WHERE a.id=b.a_id AND campo3=valore ORDER BY id;
===========================================================================
Quella che segue e’ una query su una tabella cosi’ strutturata:
| id | integer |
| utente_id | integer |
| data_lettura0 | date |
| energia_attiva_kwh_fase0_l0 | numeric(10,2) |
| energia_attiva_kwh_fase1_l0 | numeric(10,2) |
| energia_attiva_kwh_fase2_l0 | numeric(10,2) |
| energia_attiva_kwh_fase3_l0 | numeric(10,2) |
| totale_energia_attiva_kwh_l0 | numeric(12,2) |
| data_lettura1 | date |
| energia_attiva_kwh_fase0_l1 | numeric(10,2) |
| energia_attiva_kwh_fase1_l1 | numeric(10,2) |
| energia_attiva_kwh_fase2_l1 | numeric(10,2) |
| energia_attiva_kwh_fase3_l1 | numeric(10,2) |
| totale_energia_attiva_kwh_l1 | numeric(12,2) |
| data_lettura2 | date |
| energia_attiva_kwh_fase0_l2 | numeric(10,2) |
| energia_attiva_kwh_fase1_l2 | numeric(10,2) |
| energia_attiva_kwh_fase2_l2 | numeric(10,2) |
| energia_attiva_kwh_fase3_l2 | numeric(10,2) |
| totale_energia_attiva_kwh_l2 | numeric(12,2) |
| data_lettura3 | date |
| energia_attiva_kwh_fase0_l3 | numeric(10,2) |
| energia_attiva_kwh_fase1_l3 | numeric(10,2) |
| energia_attiva_kwh_fase2_l3 | numeric(10,2) |
| energia_attiva_kwh_fase3_l3 | numeric(10,2) |
| totale_energia_attiva_kwh_l3 | numeric(12,2) |
| anno | character varying(4) |
| inizio_anno | date |
| fine_anno | date |
| consumo_anno | integer |
# query per aggiornare la tabella delle letture (in un db che contiene le letture dei consumi di contatori elettrici) calcolando il consumo_anno nel caso in cui data_lettura0!=data_lettura1 per l’anno=’2009′:
energia_django=> UPDATE manager_letturailluminazione SET consumo_anno=(totale_energia_attiva_kwh_l3-totale_energia_attiva_kwh_l1)+((totale_energia_attiva_kwh_l1-totale_energia_attiva_kwh_l0)/(data_lettura1-data_lettura0)*(data_lettura1-(to_date(anno,’YYYYMMDD’)-1)))-((totale_energia_attiva_kwh_l1-totale_energia_attiva_kwh_l0)/(data_lettura1-data_lettura0)*(data_lettura3-(to_date(anno,’YYYYMMDD’)+364))) WHERE anno=’2009′ AND data_lettura0!=data_lettura1;
| id | integer |
GFOSS-DAY 2011 | Foggia
Pubblicato da flaviorigolon in blogging il 23 novembre 2011
Oggi 24 novembre 2011 inizia il quarto GFOSS-DAY. Dopo gli appuntamenti di Pontedera, Bolzano e Foligno è la volta di una sede pugliese.
Il programma è ricchissimo e denso di temi e da oggi è anche attivo, grazie all’università, il canale streaming a questo indirizzo: http://www.media.unifg.it/gfoss/
accorrete numerosi!
docky e la barra nera
Pubblicato da flaviorigolon in linuxing il 3 novembre 2011
Ho provato ad installare docky.
L’installazione avviene tramite apt o synaptic:
# apt-get install docky
Unico inconveniente iniziale è la presenza di una fastidiosissima fascia nera a lato (o sotto, a seconda del punto in cui abbiamo agganciato docky). Di questo veniamo anche avvisati da un messaggio che recita più o meno così “…enable composting…“. Per ovviare al problema è necessario un Compositing window manager. Per abilitarlo in Metacity agire come segue:
- lanciamo gconf-editor:
$ gconf-editor
Sul frame di sinistra ci posizioniamo su “apps > metacity > general“; poi, sulla destra, spuntiamo il checkbox in corrispondenza della voce “compositing_manager“.
Fatto: la barra nera dovrebbe scomparire.
Postgresql | Postgis | modificare i valori dei campi di una vista
Pubblicato da flaviorigolon in db-ing & geodb-ing, mapping il 31 ottobre 2011
Lavorando con Postgresql|Postgis mi capita spesso di avere delle tavole come viste “View” ottenute dal join di una tabella geomerica e di una tabella non-geometrica. Esempio: la tabella geometrica contiene poligoni (edifici) con un campo chiave (es= scheda); la tabella alfanumerica contiene tutti i dati relativi a quegli edifici + un campo chiave “scheda” come la prima.
Questo perché, in un lavoro svolto, un utente si occupava di gestire la parte geometrica (mediante QGIS) mentre un altro utente caricava i dati alfanumerici relativi ad un rilievo di edifici mediante interfaccia web (via PHP).
In un secondo momento quindi è stata creata una join fra le due tabelle in modo da generare tavole tematiche sulle condizioni e sull’uso di quegli edifici.
Ecco la View creata (siano “schede” e “schede_nogeom” rispettivamente la tabella geometrica e non-geometrica)
=> CREATE VIEW schede_cartogr AS SELECT scheda_nogeom.grado, scheda_nogeom.altezza, scheda_nogeom.volume, scheda_nogeom.piani, scheda_nogeom.note, scheda_nogeom.stcontetto, scheda_nogeom.punttetto, scheda_nogeom.stconprosp, scheda_nogeom.puntprosp, scheda_nogeom.stconserr, scheda_nogeom.puntserr, scheda_nogeom.stconsolai, scheda_nogeom.puntsolai, scheda_nogeom.stconmurat, scheda_nogeom.stcompl, scheda_nogeom.puntcompl, scheda_nogeom.d_uso_pint, scheda_nogeom.d_uso_pt, scheda_nogeom.d_uso_p1, scheda_nogeom.d_uso_p2, scheda_nogeom.d_uso_p3, scheda_nogeom.d_uso_p4, scheda_nogeom.d_uso_p5, scheda_nogeom.d_uso_compl, scheda_nogeom.d_uso_progetto, scheda_nogeom.d_uso_comp_grafica, scheda_nogeom.essenze_arboree, scheda_nogeom.emerg_arch, scheda_nogeom.h_pint, scheda_nogeom.h_pt, scheda_nogeom.h_p1, scheda_nogeom.h_p2, scheda_nogeom.h_p3, scheda_nogeom.h_p4, scheda_nogeom.h_p5, scheda_nogeom.vol_pint, scheda_nogeom.vol_pt, scheda_nogeom.vol_p1, scheda_nogeom.vol_p2, scheda_nogeom.vol_p3, scheda_nogeom.vol_p4, scheda_nogeom.vol_p5, scheda.area_gis, scheda_nogeom.foto1, scheda_nogeom.estratto_cartografico, scheda_nogeom.vol_residenza, scheda_nogeom.vol_comm_dir, scheda_nogeom.vol_artigianale, scheda_nogeom.vol_pubblico, scheda_nogeom.vol_misto, scheda_nogeom.puntmurat, scheda_nogeom.d_uso_vigente, scheda.gid, scheda.the_geom, scheda.scheda FROM scheda JOIN scheda_nogeom ON scheda.scheda::text = scheda_nogeom.scheda::text;
- Caricando questa vista in QGIS riusciamo quindi a consultare geometrie e tutti i valori colelgati. Ma se ad un certo punto voglio modificare un valore o alcuni valori della tabella? Abilitando l’editing sul layer “schede_cartogr” vediamo che possiamo modificare i valori ma al momento del salvataggio veniamo avvisati che non è possibile. Ci viene allora in aiuto la creazione di un RULE con istruzione “DO INSTEAD” in Postgresql . In sostanza si tratta di una regola che consente di modificare la (o le) tabelle origine agendo sulla vista.
In generale la sintassi è la seguente:
>= CREATE RULE nome_rule_da_creare AS ON UPDATE TO nome_della_view DO INSTEAD UPDATE nome_tabella_origine SET nome_campo=NEW.nome_campo WHERE campo_chiave=NEW.campo_chiave;
Ecco la definizione del RULE che ho usato:
=>CREATE RULE update_grado_schede_cartogr AS ON UPDATE TO schede_cartogr DO INSTEAD UPDATE scheda_nogeom SET grado=NEW.grado WHERE scheda=NEW.scheda;
D’ora in avanti possiamo modificare da QGIS il valore del campo “grado“; verrà aggiornato di conseguenza il valore della tabella originale.












