sabato 20 dicembre 2014

Calendario dell'Avvento ITPUG: 20 Dicembre

Vorrei introdurre una utility con la quale sto spendendo un po' di tempo e che, anche se non direttamente collegata a PostgreSQL, può semplificare la gestione di un database: sqitch.
Sqitch funziona con molti database, fra i quali ovviamente PostgreSQL, producendo degli script sql che vengono usati per fare il deploy/aggiornamento/test di un database.
Sqitch concettualmente funziona un po' come un repository Git/hg:
  • si installa uno schema "sqitch" nel database sotto controllo;
  • si usa questo schema per memorizzare le modifiche effettuate e "firmate" con un hash crittografico
Il tutto è trasparente all'utente, che usa il solo comando "sqitch" un po' come si usa git (e molti comandi e il loro output sono simili, come ad esempio log, status, add).
Attenzione però che sqitch non sostituisce un sistema di controllo delle versioni, quindi è buona norma usare sqitch tenendo comunque gli script SQL sotto controllo delle versioni.

Ecco un rapidissimo esempio per la generazione di due tabelle in un database (demodb) esistente.

  • crare un nuovo progetto e definire il database

% sqitch --engine pg init itpug
% sqitch target add itpug db:pg://luca:pwd@localhost/demodb

così facendo si crea un progetto "itpug" e si definisce che quando ci si riferisce al database "itpug" si punta in realtà a demodb.

  • si aggiunge lo script per la prima tabella

% sqitch add authors -m "Tabella autori"                                                        
Created deploy/authors.sql
Created revert/authors.sql
Created verify/authors.sql
Added "authors" to sqitch.plan
% echo "CREATE TABLE authors( pk serial NOT NULL, name text NOT NULL, primary key(pk));" > deploy/authors.sql
% echo "DROP TABLE authors CASCADE;" > revert/authors.sql


così facendo sqitch crea tre script sql (vuoti) per il deploy, l'undeploy e la verifica (qui lasciato vuoto).

  • si crea una tabella con dipendenza dalla precedente, così da informare sqitch in che ordine le modifiche al database vanno applicate

% sqitch add posts --requires authors -m "Tabella dei post"                                      
Created deploy/posts.sql
Created revert/posts.sql
Created verify/posts.sql
Added "posts [authors]" to sqitch.plan
% echo "CREATE TABLE posts( pk serial NOT NULL, content text , authors_pk integer, primary key(pk), foreign key(authors_pk) references authors(pk) );" > deploy/posts.sql
% echo "DROP TABLE posts;" > revert/posts.sql


  • deploy del database, e si nota come sqitch si colleghi a demodb per creare le tabelle nel giusto ordine.

% sqitch deploy itpug                                                                            
Adding registry tables to itpug
Deploying changes to itpug
  + authors .. psql:deploy/authors.sql:1: NOTICE:  CREATE TABLE will create implicit sequence "authors_pk_seq" for serial column "authors.pk"
psql:deploy/authors.sql:1: NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "authors_pkey" for table "authors"
ok
  + posts .... psql:deploy/posts.sql:9: NOTICE:  CREATE TABLE will create implicit sequence "posts_pk_seq" for serial column "posts.pk"
psql:deploy/posts.sql:9: NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "posts_pkey" for table "posts"
ok


Da qui in avanti si può usare "log" o "status" per sapere in che stato ci si trova, se ci sono script non ancora inviati al server, ecc.
Occorre però specificare sempre a quale database si fa riferimento (che qui è stato denominato itpug per comodità). Se ad esempio eseguiamo status fra due deploy si avrebbe:

% sqitch status itpug                                                                            
# On database itpug
# Project:  itpug
# Change:   173fb5f9cf9f5048e5b2baf6e6699984b4fdb9fe
# Name:     authors
# By:       Luca Ferrari,,,
#
Undeployed change:
  * posts



notare come l'output sia simile a quello di un rcs distribuito, anche se qui git/hg/bzr non sono nemmeno stati toccati.


Ultimissima cosa: gli script crewti da sqitch non sono "vuoti" ma contengono  informazioni su come gestire le dipendenze. Di conseguenza, sovrascrivere tali script come ho fatto nel passo 3 è sbagliato. Meglio quindi editarli nel proprio editor preferito. Per meglio comprendere, consideriamo di aggiungere un'altra tabella con la dipendenza dalle altre due:

% sqitch add statistics --requires authors --requires posts                                      
Created deploy/statistics.sql
Created revert/statistics.sql
Created verify/statistics.sql
Added "statistics [authors posts]" to sqitch.plan

% cat deploy/statistics.sql                                                                      
-- Deploy statistics
-- requires: authors
-- requires: posts

BEGIN;

-- XXX Add DDLs here.

COMMIT;


Ecco quindi che quei commenti sql all'inizio del file indicano a sqitch come procedere.

Se si vuole esplorare come sqitch gestisce il database e la sua storia si può partire dalla tabella sqitch.changes.

Nessun commento: