Ho ripescato una vecchia box con ancora Sarge sopra.
Ho deciso di aggiornarla per portarla alla versione Lenny (attualmente stable di Debian).
Innumerevoli porconi sono stati lanciati causa conflitti vari legati a python2.3 (che mi ero colpevolmente dimenticato di aggiornare prima del resto) e ad un altro paio di conflitti.
Una vecchia versione di postgres (7.4.x) aveva due (inutili) database nella pancia che dopo l’aggiornamento non erano piu’ nel server 8.3 (no migrazione automatica fra le versioni di Pg) – ma ancora presenti nel filesystem (in /var/lib/postgres/data/ ).
Raccatta la vecchia versione sul sito ftp di Postgres: ftp://ftp-archives.postgresql.org.
Installa la vecchia versione da qualche parte in /opt specificando il prefisso in fase di configurazione (per evitare bordelli), make e make install.
… Fai partire il postmaster locale che punta al repository vecchio:
FAIL
DETAIL: The database cluster was initialized with HAVE_INT64_TIMESTAMP but the server was compiled without HAVE_INT64_TIMESTAMP.
Che cosa non va? Ravanando sul web capisco che serve l’obzione: ‘–enable-integer-datetimes‘ in configurazione. Pulisci la dir, riconfigura, ricompila e ribuilda. Questa volta parte.
Non serve neanche controllare, se non si vuole: dumpall diretto sul server, salvataggio dei dati in un file, control+C per chiudere il server vecchia versione nonchè remove… infine riavvio di quello nuovo.
Nota: La prossima volta, meglio fare il dump prima.
Sfruttando Slackbuild, ho installato postgres 9.0.1 sull’e3pc.
Le possibilità che l’rdbms non pianti tutto sono poche, ma solo il futuro ci dirà se quei 512 MB di RAM riescono a reggere Apache+Pg+Catalyst.
Dopo mezz’oretta di setting vari (ho tolto dalla configurazione di postgres python, tcl e ldap), compilazione, inizializzazione del db (man initdb):
postgres=# SELECT VERSION();
version
---------------------------------------------------------------------------------------
PostgreSQL 9.0.1 on i486-slackware-linux-gnu, compiled by GCC gcc (GCC) 4.4.4, 32-bit
(1 row)
Creato il ruolo per l’utente… pare andare tutto bene.
postgres=# CREATE ROLE sim NOSUPERUSER CREATEDB NOCREATEROLE INHERIT LOGIN;
CREATE ROLE
postgres=# \du
List of roles
Role name | Attributes | Member of
-----------+-----------------------------------+-----------
postgres | Superuser, Create role, Create DB | {}
sim | Create DB | {}
Riguardo i driver di Perl ho preferito installare DBD::Pg da slackbuild invece che con cpanm, perchè CPAN mi dava alcuni errori.
Lavorando su un postgres vecchiotto avevo scritto una riga di codice php che con le nuove versioni non è accettata per questioni di casting.
Visto che in effetti il risparmio è notevole, oltre che più corretto, segnalo la funzione TO_CHAR (che ha nelle opzioni quello che spesso serve per fare manipolazioni di date).
Quello che prima era trovato concatenando due stringhe ricavate da DATE_PART (per prendere una parte di un timestamp without date zone) e facendolo passare per LPAD in due cifre riempito con caratteri 0:
( LPAD( DATE_PART('day',file_upped), 2,'0') ||
LPAD( DATE_PART('month',file_upped), 2,'0') )
ora è trovato con questa semplice funzione che ha fra le opzioni già la possibilità di avere giorno e mese in campo di 2 cifre:
TO_CHAR(file_upped,'DDMM')
Mea culpa. Negli ultimi mesi ho dovuto dare un occhio in più alle query SQL e così sto ripassando e imparando un sacco di cose che prima mi erano sconosciute.
Una robba estremamente utile che prima facevo (male) “tagliando” in perl i dati fetch’ati dal database è prendere raggruppamenti di dati gruppati secondo una clausola.
La sostanza è che ultimamente mi ero ritrovato molto a mio agio nel raggruppare dati grazie all’opzione GROUP BY conteggiando le voci con COUNT. Il problema era che non sapevo come fare un taglio sul conteggio, e così scremavo i dati in perl dopo averli raccolti tutti dal database.
Questa cosa palesemente non risultava buona.
Quindi dopo prezioso suggerimento ho letto questa paginetta e ho trovato HAVING.
Niente di trascendentale, ma per me salvifico.
=> SELECT nome, COUNT(*) FROM lista
GROUP BY nome HAVING COUNT(*) > 600 ORDER BY count DESC;
Dopo aver filtrato (eventualmente) i dati con WHERE, l’input derivato dalla tabella può essere soggetto al GROUP BY per raggruppare dati, e i raggruppamenti possono essere scremati dalla clausola HAVING.
GROUP BY viene utilizzato per raggruppare insieme quelle righe della tabella che condividono gli stessi valori in tutte le colonne selezionate.
I raggruppamenti vanno d’accordo con funzioni che aggregano espressioni – come SUM() o COUNT().
Piccole scoperte per grandi pivelli.
Avevo necessità di ricopiare una tabella già fatta da un database postgres (8.3) ad un altro.
Come fare per avere la stessa linea “CREATE” se l’history non riesce a recuperare così tanto indietro nel tempo?
Semplice: usare pg_dump.
pg_dump è l’utility per fare il backup dei database Postgres. Con un paio di opzioni, ha fatto perfettamente al caso mio:
# pg_dump nome_database --schema-only -t nome_tabella
L’opzione -t o –table serve a specificare la tabella che abbiamo scelto, e –schema-only dumpa solo la definizione dei data (non i dati stessi).
Senza specificare un output, pg_dump spamma su STDOUT, quindi con un taglia e incolla il gioco è fatto.
Un bigint occupa 8 bytes.
Dal manuale di postgres:
bigint 8 bytes large-range integer range: -9223372036854775808 to 9223372036854775807
| Byte | Bit | Potenza | Range decimale | Ordine |
| 1 | 8 | 28 | 0 .. 255 | 100 |
| 2 | 16 | 216 | 0 .. 65 535 | 10K |
| 4 | 32 | 232 | 0 .. 4 294 967 295 | 1 miliardo |
| 8 | 64 | 264 | 0 .. 18 446 744 073 709 551 615 | 1 miliardo di miliardi |
Hai voglia, oh caro spammatore, a riempirmi di record.
A forza di pistolare sui db, sto provando un po’ di tutto per vedere dove mi trovo meglio.
Un db importante sul fronte opensource è PostgreSQL (sito ufficiale e wiki per un po’ di storia).
Per creare utenze all’interno del sistema postgres è possibile utilizzare programmi da shell (createuser) o comandi da prompt (CREATE ROLE utente).
Per avere un’idea dei ruoli creati si puo’ fare un select sulla tabella pg_roles del db postgres (di default)…
postgres=# SELECT rolname FROM pg_roles ; rolname ---------- postgres odg (2 rows)
oppure usare il semplice comando \du
postgres=# \du
List of roles
Role name | Superuser | Create role | Create DB | Connections | Member of
-----------+-----------+-------------+-----------+-------------+-----------
odg | no | no | no | no limit | {}
postgres | yes | yes | yes | no limit | {}
(2 rows)
(Come si vede ho creato un ruolo extra (odg) oltre a quello di default.)