2ndQuadrant » Consulenza Database https://blog.2ndquadrant.it Il blog sui database di 2ndQuadrant Italia Thu, 25 Jan 2018 11:36:59 +0000 en-US hourly 1 http://wordpress.org/?v=4.3.15 PgTAP, l’importanza dei test in PostgreSQL – Parte 2 https://blog.2ndquadrant.it/pgtap_limportanza_dei_test_in_1/ https://blog.2ndquadrant.it/pgtap_limportanza_dei_test_in_1/#comments Fri, 28 Oct 2011 11:47:31 +0000 http://2ndblog.dev.xcon.it/pgtap_limportanza_dei_test_in_1/ In questo articolo vedremo un esempio completo di test eseguiti su un semplice set di dati.

Ci sono diversi modi di eseguire i test con PgTAP. È possibile usare pg_prove, uno script installabile attraverso il CPAN, oppure si può scrivere una funzione plpgsql che esegua i test.

In questo esempio, useremo una funzione.

Creiamo un file che contenga i test, chiamamolo risultati_test.sql.

Scriviamo la funzione che lancia i test direttamente nel file, con il nostro editr preferito.

CREATE OR REPLACE FUNCTION risultati_test()
RETURNS SETOF TEXT
AS $$
BEGIN
-- Controlliamo la presenza degli oggetti:
-- Tabella foo
RETURN NEXT tables_are(
'public',
ARRAY[ 'foo' ]
);
-- Schema nuovo_schema
RETURN NEXT schemas_are(
ARRAY['public','nuovo_schema']
);
-- Controlla che sia presente la funzione say_hello
RETURN NEXT can(
ARRAY['say_hello']
);
-- Controlla che la funzione say_hello sia scritta in SQL
RETURN NEXT function_lang_is(
'say_hello',
'sql'
);
-- Controlla che la funzione say_hello non generi errori
RETURN NEXT lives_ok(
'SELECT say_hello()'
);
-- Controlla che la tabella foo contenga esattamente certi valori
-- provate a cambiare uno dei valori ed osservare come si comporta il test
RETURN NEXT results_eq(
'SELECT 2ndquadrant_italia_mod.txt 2ndquadrant_italia.txt da_installare_pandoc hdoisajds.sh risultati step2 FROM foo',
'VALUES (1),(2),(3),(4),(5)'
);
END;
$$ LANGUAGE plpgsql;

Adesso creiamo il file che esegue questa funzione, chiamiamolo test.sql

BEGIN;
i risultati_test.sql
SELECT PLAN(6); -- Necessario!
SELECT risultati_test();
ROLLBACK;

2ndquadrant_italia_mod.txt 2ndquadrant_italia.txt da_installare_pandoc hdoisajds.sh risultati step2 La prima riga dà inizio ad una transazione. È consigliato inserire i test in una transazione che esegua un rollback prima di terminare, così da essere sicuri che lo stato del databse venga mantenuto intatto.

2ndquadrant_italia_mod.txt 2ndquadrant_italia.txt da_installare_pandoc hdoisajds.sh risultati step2 Successivamente, tramite il comando di psql i, importiamo il file risultati_test.sql, che crea la funzione che lancia i test.

2ndquadrant_italia_mod.txt 2ndquadrant_italia.txt da_installare_pandoc hdoisajds.sh risultati step2 La riga successiva, SELECT PLAN(6);, serve a specificare il numero di test che intendiamo eseguire (6 in questo caso). È necessaria e controlla che l’esecuzione di un numero di test diverso rispetto a quello specificato, restituisca un fallimento.

2ndquadrant_italia_mod.txt 2ndquadrant_italia.txt da_installare_pandoc hdoisajds.sh risultati step2 La riga SELECT risultati_test(); lancia la funzione che esegue i test.

Abbiamo finito di scrivere i nostri test, possiamo eseguirli con:

psql -f test.sql pgtap_db

Il risultato dovrebbe essere:

BEGIN
CREATE FUNCTION
plan
------
1..6
(1 row)
testfunction
------------------------------------------------------
ok 1 - Schema public should have the correct tables
ok 2 - There should be the correct schemas
ok 3 - Schema pg_temp_2 or pg_catalog or public can
ok 4 - Function say_hello() should be written in sql
ok 5
ok 6
(6 rows)
ROLLBACK

Si spiega da solo, no? :)

In effetti, lo scopo del protocollo TAP è di essere il più comprensibile possibile. Una serie di ok (in caso di successo) e di not ok (in caso di fallimento) rendono estremamente facile l’interpretazione dei test.

2ndQuadrant Italia utilizza estensivamente PgTAP, il tempo speso a scrivere i test risulta di vitale importanza per la manutenzione dei nostri progetti.

]]>
https://blog.2ndquadrant.it/pgtap_limportanza_dei_test_in_1/feed/ 0
PgTAP, l’importanza dei test in PostgreSQL https://blog.2ndquadrant.it/pgtap_limportanza_dei_test_in/ https://blog.2ndquadrant.it/pgtap_limportanza_dei_test_in/#comments Tue, 25 Oct 2011 11:26:39 +0000 http://2ndblog.dev.xcon.it/pgtap_limportanza_dei_test_in/ TAP (Test Anything Protocol) è una semplice interfaccia per i test basata su file di testo. TAP nasce col Perl, ma ad oggi ha implementazioni per i più famosi linguaggi di programmazione. PgTAP è l’implementazione di TAP in PostgreSQL.

Non mi dilungherò a descrivere il motivo per cui i test sono importanti, specialmente nell’ottica dello sviluppo agile, che 2ndQuadrant adotta con successo.

PgTAP, sfruttando una sintassi estremamente semplice, permette di testare a fondo il proprio database.

Presupponendo che PgTAP sia stato installato correttamente in un database chiamato pgtap_db, procediamo con la creazione di alcuni oggetti sui quali eseguiremo dei test.

Per informazioni circa l’installazione di PgTAP in un determinato database, rimando alla documentazione ufficiale.

$ psql -c "CREATE TABLE foo AS SELECT generate_series(1,5) AS x" pgtap_db
SELECT 1
$ psql -c "CREATE SCHEMA nuovo_schema" pgtap_db
CREATE SCHEMA
$ psql -c "CREATE FUNCTION say_hello() RETURNS TEXT LANGUAGE SQL AS $$SELECT 'Hello World'::TEXT$$;" pgtap_db
CREATE FUNCTION

Tipi di utilizzo

PgTAP può essere utilizzato per testare qualsiasi aspetto del database. In particolare:

2ndquadrant_italia_mod.txt 2ndquadrant_italia.txt da_installare_pandoc hdoisajds.sh risultati step2 Presenza di oggetti nel database 2ndquadrant_italia_mod.txt 2ndquadrant_italia.txt da_installare_pandoc hdoisajds.sh risultati step2 Controllo dell'esecuzione di query 2ndquadrant_italia_mod.txt 2ndquadrant_italia.txt da_installare_pandoc hdoisajds.sh risultati step2 Controllo dei risultati di una query 2ndquadrant_italia_mod.txt 2ndquadrant_italia.txt da_installare_pandoc hdoisajds.sh risultati step2 Altro

Descriverò in ordine questi aspetti e poi vedremo un esempio pratico.

Presenza di oggetti nel database

Si può controllare l'esistenza di qualsiasi tipo di oggetto nel database. Questo tipo di funzioni ha più o meno la stessa firma, in particolare:

*tipo_di_oggetto*_are( [schema,]  [,description] )

Dove:

2ndquadrant_italia_mod.txt 2ndquadrant_italia.txt da_installare_pandoc hdoisajds.sh risultati step2 tipo_di_oggetto è la categoria di oggetti di cui vogliamo testare la presenza, ad esempio tabelle (tables), funzioni (functions), schemi (schemas) ecc.

2ndquadrant_italia_mod.txt 2ndquadrant_italia.txt da_installare_pandoc hdoisajds.sh risultati step2 schema definisce lo schema in cui gli oggetti devono trovarsi, questo parametro ha senso solo se non si sta testando la presenza dello schema stesso.

2ndquadrant_italia_mod.txt 2ndquadrant_italia.txt da_installare_pandoc hdoisajds.sh risultati step2 array_di_nomi è un array contenente i nomi degli oggetti che devono essere presenti perchè il test abbia successo

Importante: Per avere successo, tutti gli elementi specificati nell'array devono essere presenti. In caso di assenza di almeno uno degli elementi, il test fallirà.

2ndquadrant_italia_mod.txt 2ndquadrant_italia.txt da_installare_pandoc hdoisajds.sh risultati step2 description è una descrizione del test

Nota: Ovviamente, nel caso di schemas_are, il primo parametro, schema, viene omesso.

Controllo dell'esecuzione di query

È possibile testare in modo semplice che una query venga eseguita senza o con errori. Per farlo sono disponibili le funzioni:

throws_ok( query [, errcode] [, errmsg] [, description] )
lives_ok( query [, description] )
performs_ok( query, milliseconds [, description])

Queste tre funzioni controllano rispettivamente:

2ndquadrant_italia_mod.txt 2ndquadrant_italia.txt da_installare_pandoc hdoisajds.sh risultati step2 Che la query generi un'eccezione. È possibile specificare l'errore voluto tramite il parametro errcode

2ndquadrant_italia_mod.txt 2ndquadrant_italia.txt da_installare_pandoc hdoisajds.sh risultati step2 Che la query non generi un'eccezione

2ndquadrant_italia_mod.txt 2ndquadrant_italia.txt da_installare_pandoc hdoisajds.sh risultati step2 Che la query termini entro milliseconds millisecondi

Controllo dei risultati di una query

Spesso si ha bisgno di controllare che una query restituisca esattamente un certo insieme di risultati. PgTAP ha diverse funzioni per questo scopo, la principale è:

results_eq( sql, array [, description] )

Molto intuitivamente, questo test passerà se l'insieme di risultati della query sarà esattamente uguale ai valori presenti in array. Nell'esempio completo presente più in basso, vedremo come sfruttare questa funzione.

Altro

Vi sono poi altri tipi di test, ma citiamo qui solo i più importanti. Per una lista completa invitiamo a consultare la documentazione ufficiale.

2ndquadrant_italia_mod.txt 2ndquadrant_italia.txt da_installare_pandoc hdoisajds.sh risultati step2 Per controllare qualsiasi elemento usando un'espressione regolare:

matches( anyelement, regex [, description] )

2ndquadrant_italia_mod.txt 2ndquadrant_italia.txt da_installare_pandoc hdoisajds.sh risultati step2 Per controllare che un utente sia un superutente:

is_superuser( user [, description] )

2ndquadrant_italia_mod.txt 2ndquadrant_italia.txt da_installare_pandoc hdoisajds.sh risultati step2 Per controllare che una funzione sia scritta in un determinato linguaggio:

function_lang_is( [schema,] function [, args[]] , language [, description])

2ndquadrant_italia_mod.txt 2ndquadrant_italia.txt da_installare_pandoc hdoisajds.sh risultati step2 Per stampare messaggi di diagnostica che non interferiscano con i test:

diag( text )

Nel prossimo articolo vedremo un esempio pratico, dove eseguiremo dei test su un set di oggetti creati per l'occasione.

A presto!

]]>
https://blog.2ndquadrant.it/pgtap_limportanza_dei_test_in/feed/ 0
Importare dati in Greenplum da più file csv con Talend https://blog.2ndquadrant.it/etl_con_talend_su_greenplum/ https://blog.2ndquadrant.it/etl_con_talend_su_greenplum/#comments Wed, 14 Sep 2011 15:05:01 +0000 http://2ndblog.dev.xcon.it/etl_con_talend_su_greenplum/ Lavorando con i database, capita spesso di dover importare i dati direttamente da uno o più file CSV. Esistono molteplici strumenti per farlo e spaziano dal copy di psql, via linea di comando, ai più complessi sistemi di ETL come Talend o Kettle. In questo articolo analizzeremo la capacità di Talend di interfacciarsi con un database Greenplum per importare i dati contenuti in 2 file di testo.

Dopo aver scaricato Talend Open Studio (reperibile dal sito di Talend) e dopo averlo installato, possiamo procedere creando un nuovo progetto, e all’interno di questo un nuovo job.

Creiamo quindi le connessioni alle risorse che ci serviranno durante l’importazione, ovvero la connessione al database remoto e i due file csv.

Nella sezione Metadata dell’interfaccia di Talend, aggiungiamo la connessione a Greenplum, dopo aver inserito il nome e i parametri di connessione, il programma creerà un nuovo oggetto di tipo DbConnection.

Cliccando su questo con il tasto destro e selezionando l’opzione “recupera schema”, sarà possibile selezionare le tabelle su cui vogliamo lavorare, nel nostro caso la tabella states e la tabella users.

Aggiungiamo ora i file contenenti i dati. Subito sotto l’icona delle connessioni ai database (DB connections), troviamo il gruppo dei file CSV, come precedentemente fatto per i database, clicchiamo con il tasto destro sul gruppo e poi su “crea file delimitato”.

Nella prima schermata del wizard che si aprirà, ci verrà richiesto di inserire un nome e una descrizione per la risorsa che stiamo creando. Si passa quindi allo step due, nel quale dobbiamo identificare il file di testo a cui vogliamo riferirci, e la sua codifica.

Una volta fatto sarà possibile possibile passare al terzo step, nel quale dobbiamo istruire Talend su come gestire le colonne del CSV. In questa schermata è possibile : selezionare l’encoding del file (1), i separatori di campo e i caratteri di fine linea (2), e qualora fosse necessario, segnalare quante e quali linee devono essere ignorate sia all’inizio che alla fine del file (3).

È inoltre possibile segnalare a Talend di utilizzare la prima riga come “schema” del CSV, in maniera che possa prendere i nomi delle colonne direttamente dal file, risparmiando all’utilizzatore l’inserimento manuale del nome delle colonne ( 4 ).

Nel quarto step resta solo da: modificare lo schema del file che stiamo associando, controllare e modificare i tipi di dato riconosciuti in automatico per ogni colonna e, qualora non fossero stati riconosciuti in automatico dalla testata del CSV, modificare i nomi delle colonne e la lunghezza dei campi.

Completato il 4° passo del wizard, il file è correttamente associato all’applicazione e pronto per essere usato.

Una volta aggiunte tutte le risorse che intendiamo utilizzare, è possibile procedere con la creazione del job. Trasciniamo quindi i due file sull’editor visuale del job, e selezioniamo tFileInputDelimited come tipo di file.

Dalla connessione a Greenplum precedentemente creata invece, trasciniamo sull’editor le due tabelle di destinazione (nel nostro caso states e users), e selezioniamo come tipo tGreenplumOutput.

Inseriamo ora un oggetto di tipo tMap – che si trova nella palette degli strumenti alla destra dell’editor visuale – nella cartella “elaborazione” e posizioniamolo fra il file CSV contenente gli stati da importare e la tabella di Greenplum di destinazione.

Colleghiamo il file al componente tMap (clic con il destro sul file -> riga -> main) e il componente tMap alla tabella di destinazione (clic destro sulla tabella -> riga -> nuovo output). Una volta collegati fra di loro i componenti possiamo fare doppio click sull’oggetto tMap che permette di associare le righe del file da importare a quelle della tabella di destinazione.

Trascinando i vari campi dalla tabella di sinistra a quella di destra , è possibile associare ogni colonna del file alla colonna relativa sulla tabella di destinazione. Cliccando su ok salveremo l’associazione appena effetuata e i dati sono pronti per essere importati dal file di origine alla tabella di destinazione.

Aggiungiamo ora l’importazione di una lista di utenti dal secondo csv, durante l’importazione è necessario fare lookup sulla tabella degli stati appena riempita, in maniera da verificare l’associazione “utente -> stato”, riga per riga. Con il gergo lookup si intende la ricerca di un valore all’interno di un dizionario, utilizzando una chiave al fine di recuperare un ID (solitamente la chiave primaria di quell’oggetto nel database, per garantire integrità referenziale).

Aggiungiamo quindi un oggetto tMap fra il file CSV con gli utenti e la tabella di destinazione, inoltre dalla lista delle tabelle di Greenplum trasciniamo nuovamente la tabella contenente gli stati sulla finestra dell’editor visuale, selezionando come tipo tGreenplumInput.

Colleghiamo quindi i tre elementi al componente tMap, come e’ stato fatto precedentemente.

Adesso eseguiamo il mapping fra i tre elementi: questa volta il campo idState del CSV deve essere mappato sul campo idState della tabella states (row3) e quest’ultimo deve essere collegato alla tabella utenti di destinazione. In questa maniera per ogni linea del CSV viene eseguito il lookup sulla tabella stati, assicurando così l’integrità della relazione “Utente – Stato”.

Per concludere, facciamo in modo che prima venga eseguita l’importazione dei dati relativi agli stati. Successivamente, quelli degli utenti, in modo da poter eseguire correttamente il lookup. Tracciamo quindi una riga di tipo OnComponentOK (click destro -> attivare -> onComponentOk) dal componente di output della tabella stati a quello di input degli utenti (il file CSV).

In questo modo prima verrano importati gli stati e solo in caso di successo verranno impotati gli utenti.

Adesso basterà cercare il tab di esecuzione nella parte bassa dell’area di lavoro e premere il tasto run per fare in modo che il nostro job venga eseguito.

]]>
https://blog.2ndquadrant.it/etl_con_talend_su_greenplum/feed/ 0
Come utilizzare la Virtual Machine di Greenplum Community Edition con VirtualBox https://blog.2ndquadrant.it/greenplum_vmware_virtualbox/ https://blog.2ndquadrant.it/greenplum_vmware_virtualbox/#comments Fri, 26 Aug 2011 16:30:03 +0000 http://2ndblog.dev.xcon.it/greenplum_vmware_virtualbox/ Fra i vari download disponibili nella sezione community del sito di Greenplum, è possibile trovare una Virtual Machine con il software già configurato e installato su un sistema CentOs.

La virtual machine è fatta per funzionare con VmWare, ma con qualche piccola attenzione e per puri scopi di valutazione di Greenplum, è possibile farla funzionare anche con VirtualBox.

Dopo aver installato l’ultima versione di VirtualBox (disponibile su http://www.virtualbox.org/wiki/Downloads ) è possibile scaricare l’immagine di VmWare da http://www.greenplum.com/community/downloads/. Una volta ultimato il download, e dopo aver scompattato l’archivio, è possibile procedere con l’installazione.

Innanzitutto creiamo una nuova virtual machine, semplicemente cliccando sul tasto “Nuovo” in alto a sinistra nella finestra di VirtualBox; avremo così accesso al wizard di creazione virtual machine. Dopo la prima schermata introduttiva, nella seconda ci troveremo a scegliere il nome della macchina, che deve essere univoco, e il tipo di sistema operativo. Nel primo dropdown deve essere selezionato “Linux”, mentre come versione va scelta Red Hat a 64 bit, essendo la VM basata su CentOs.

Nel terzo step del wizard viene chiesta quanta RAM deve essere allocata alla virtual machine. Di default il programma ne assegna 512 MB, ma per il tipo di ambiente che sta per essere eseguito potrebbero essere pochi. Consiglio quindi di aumentare a 1024 MB la RAM da allocare.

Nella quarta schermata deve essere deselezionato il flag “disco di avvio”. Una volta cliccato su continua, VirtualBox ci avvertirà che, continuando senza disco, non potremo fare il boot della macchina. Il disco di boot verrà aggiunto manualmente in seguito: selezionare pertanto “continua”. Nell’ultima schermata bisogna semplicemente cliccare su “continua” per completare la creazione della VM.

E’ il momento di aggiungere il disco di avvio alla VM appena creata: entrare nelle impostazioni relative alla virtual machine e andare nella sezione “archiviazione”. Nell’albero dei controller deve essere selezionata la voce “controller ide” , cliccando sull’immagine del disco con il “+” verde in basso a sinistra, comparirà l’opzione “aggiungi disco fisso. Alla domanda successiva, relativa alla creazione di un disco vuoto, deve essere selezionata la voce “scegli disco esistente”. E’ possibile ora navigare fino alla posizione dove è stata scompattata l’immagine della virtual machine, e selezionare il primo della serie di files che compongo l’immagine, in questo caso il file si chiama “CentOS 64-bit-cl1.vmdk”, riconoscibile come primo della serie per l’assenza di numeri sequenziali nel nome.

Dopo aver aggiunto il disco la virtual machine è pronta per essere avviata. Completata la fase di boot, il sistema proverà a far partire l’ambiente grafico, ma, essendo il sistema configurato per funzionare con VmWare, i driver attualmente installati non possono funzionare con la scheda video virtuale di VirtualBox. Verrà quindi mostrata una schermata blu di errore che chiederà se devono essere visualizzati i log. Dopo aver risposto “No”, verrà mostrata un’ulteriore schermata per l’autoconfigurazione di GDM. Anche in questo caso non è quello che serve, quindi la risposta da dare è nuovamente “No”.

Si viene quindi condotti a una schermata di login su shell; per accedere l’ username è root, la password è password.

Essendo ora amministratori della macchina è possibile lanciare lo script che disinstallerà i driver specifici di VMWare: vmware-uninstall-tools.pl.

lo script eseguirà la disinstallazione completa dei driver. Una volta terminata, è necessario riavviare il sistema. Subito dopo il riavvio ci troveremo nuovamente di fronte alle domande relative al log e all’autoconfigurazione di GDM. Rifiutando come prima, sarà possibile effettuare nuovamente login da shell come root.

E’ ora possibile installare i driver di VirtualBox. Per farlo è necessario andare nel menù “dispositivi” di VirtualBox, e selezionare l’opzione “installa guest additions”. A questo punto tornando sulla shell è possibile lanciare il comando:

mount /dev/cdrom /media

Andiamo adesso nella directory media:

cd /media

e eseguiamo lo script di installazione dei driver di VirtualBox:

bash VboxLinuxAdditions.run

Purtroppo a causa del kernel troppo vecchio di questa macchina virtuale, non sarà possibile avere l’accelerazione grafica, ma adesso il sistema è pronto per funzionare.

Dopo un ultimo riavvio, il sistema sarà correttamente funzionante anche su VirtualBox, e potrete pertanto avviare i primi passi con Greenplum direttamente da questo sistema.

Ricordiamo che il presente articolo deve essere considerato solamente per scopi di valutazione delle funzionalità di Greenplum Community Edition. Per ottenere performance maggiori, si consiglia di installare Greenplum Community Edition su sistemi non virtuali.

Buon divertimento!

]]>
https://blog.2ndquadrant.it/greenplum_vmware_virtualbox/feed/ 0
Bytea in PostgreSQL con PHP e PDO https://blog.2ndquadrant.it/postgresql_bytea_php_pdo/ https://blog.2ndquadrant.it/postgresql_bytea_php_pdo/#comments Sun, 17 Jan 2010 09:55:15 +0000 http://2ndblog.dev.xcon.it/postgresql_bytea_php_pdo/ Nell’articolo precedente abbiamo visto le basi per la connessione a database PostgreSQL in PHP utilizzando PDO. In questo breve documento vedremo come effettuare inserimenti e come recuperare dati memorizzati in formato bytea in un database PostgreSQL utilizzando PHP con PDO. Il tipo di dato bytea è un’alternativa fornita da PostgreSQL per la memorizzazione di oggetti binari (nei comuni DBMS e in SQL questi sono conosciuti come binary large objects o semplicemente BLOB). La gestione dei bytea è molto più semplice della gestione dei BLOB tradizionali, e questo è uno dei motivi del successo di questo tipo di dato in Postgres.

Come definito nella documentazione di PostgreSQL sui tipi di dato binario, il tipo di dato bytea permette la memorizzazione di stringhe binarie (vere e proprie sequenze di byte) di lunghezza variabile in un campo di una tabella. PostgreSQL fornisce le specifiche per la codifica di queste stringhe binarie, tuttavia i linguaggi di programmazione e le librerie di astrazione più comuni mettono a disposizione meccanismi automatici e trasparenti per la serializzazione/deserializzazione dei dati. PDO per PHP è uno di questi. Purtroppo, la documentazione sul tipo di dato bytea di PostgreSQL è molto scarsa e uno degli obiettivi di questo articolo è di dimostrare con un esempio quanto questo sia facile. Gli esempi forniti sono molto semplici e il loro scopo è puramente didattico. Non sono da utilizzare "così come sono" in un ambiente di produzione in quanto non sono gestiti gli errori e le eccezioni.

La tabella ‘documenti’

Supponiamo di avere una tabella chiamata documenti, così composta:


CREATE TABLE documenti (
id serial,
documento bytea
);

E supponiamo di volere memorizzare il contenuto compresso di una stringa di testo dentro il campo documento. In PHP è possibile comprimere il contenuto di una stringa con il comando gzencode. La funzione ritorna una stringa binaria che può essere memorizzata come oggetto binario in PostgreSQL.


// $docstr contiene la stringa originale (ad esempio un documento HTML)
// $gzdoc contiene la stringa binaria (il documento HTML compresso ad esempio)
$gzdoc = gzencode($docstr);

Inserimento di un campo bytea

Il primo passo consiste nella creazione della query preparata:


$stmt = $connection->prepare('INSERT INTO documenti (documento) VALUES (?)');

Il passo successivo è quello di informare PDO che il primo parametro della query preparata è un tipo di dato bytea e deve essere trattato come un dato binario. La costante PDO da utilizzare è PDO::PARAM_LOB.


$stmt->bindParam(1, $gzdoc, PDO::PARAM_LOB);

L’ultimo passo è l’esecuzione della query:


$stmt->execute();

Selezione di un campo bytea

Il modo migliore per recuperare il contenuto di un campo bytea è quello di associare una colonna a una variabile utilizzando bindColumn della classe PDOStatement. Il codice di esempio è fornito qui sotto:


// la variabile $id contiene l'ID del documento da recuperare
$stmt = $dbh->prepare('SELECT documento FROM documenti WHERE id = ?');
$stmt->bindParam(1, $id, PDO::PARAM_INT);
$stmt->execute(); // esegue la query
// Associa la prima colonna di risultato alla variabile locale
// $gzdoc che conterrà il valore del campo 'documento'
$stmt->bindColumn(1, $gzdoc);
$stmt->fetch(PDO::FETCH_BOUND);
// echo $gzdoc; // visualizza la stringa binaria
// echo gzdecode($gzdoc); // visualizza la stringa originale

Conclusioni

Questa breve guida ha esposto un piccolo esempio di inserimento e di selezione di dati binari in PostgreSQL memorizzati in campi bytea utilizzando PHP e PDO. Il tipo di dato bytea rappresenta una delle caratteristiche peculiari di Postgres nel trattamento di dati binari e semplifica notevolmente la gestione dei backup logici. In MySQL un tipo di dato simile è costituito dal MEDIUMBLOB. Se siete interessati a approfondire questo argomento, non esitate a contattarmi oppure a partecipare a uno dei corsi 2ndQuadrant su PHP.

]]>
https://blog.2ndquadrant.it/postgresql_bytea_php_pdo/feed/ 0
Connettersi a PostgreSQL con PHP utilizzando PDO https://blog.2ndquadrant.it/php_postgresql_pdo_1/ https://blog.2ndquadrant.it/php_postgresql_pdo_1/#comments Tue, 10 Nov 2009 22:49:13 +0000 http://2ndblog.dev.xcon.it/php_postgresql_pdo_1/ PDO per PHP 5 rappresenta la miglior tecnologia al momento a disposizione per accedere a database utilizzando PHP, in quanto incorpora i vantaggi dell’approccio OO, delle prestazioni e infine di genericità e astrazione nell’accesso ai dati. In questo breve articolo vediamo alcuni esempi per la connessione utilizzando il driver PostgreSQL.

PHP 5 mette a disposizione degli sviluppatori PDO, PHP Data Objects, una estensione molto potente per la connessione ai database utilizzando una interfaccia consistente, universale e leggera. L’accesso ai singoli database avviene sulla base di un driver PDO specifico (ad esempio esiste il driver PDO per PostgreSQL, come quello per MySQL, …).

In gergo tecnico, PDO fornisce un livello di astrazione all’accesso ai dati. A differenza di framework di astrazione dal database (ad esempio Pear MDB2 o l’obsoleto Pear DB), PDO accede al database utilizzando direttamente le funzioni native messe a disposizione dal driver specifico.

Al momento rappresenta sicuramente il miglior modo per accedere a un sistema di gestione di database con PHP.

Premesse

L’esempio utilizza PHP 5.3 su Mac OS X, installato con Mac Ports. E’ necessario installare PDO con il driver per PostgreSQL.

Si presuppone che si abbia una buona conoscenza di PostgreSQL, che si sia in grado di creare un utente, un database e una tabella.

Gli esempi sono stati testati su PostgreSQL 8.4.1, ma i concetti sono applicabili anche su versioni precedenti (si consiglia comunque di utilizzare almeno PostgreSQL 8.3 in produzione): il server PostgreSQL si presuppone installato sulla stessa macchina del PHP in ascolto sulla porta di default 5432.

Infine, vengono riportati soltanto alcuni snippet (pezzi) di codice, quelli pertinenti all’utilizzo di PDO con PostgreSQL: sarà premura del programmatore includerli all’interno delle proprie applicazioni.

Come utente postgres, creare l’utente pdo e il database pdo, eseguengo le seguenti istruzioni SQL tramite psql (si possono utilizzare anche altri prodotti per l’amministrazione di database PostgreSQL come PHPPgAdmin, pgAdmin III oppure l’alternativa commerciale Navicat):


CREATE USER pdo WITH ENCRYPTED PASSWORD 'pdo';
CREATE DATABASE pdo WITH OWNER pdo ENCODING 'UTF8';

Connettersi al database pdo come utente pdo e creare la tabella bands:


CREATE TABLE bands (
id SERIAL PRIMARY KEY,
band_name VARCHAR(256) NOT NULL
);

Connessione tramite PHP

Per connettersi con PHP tramite PDO al database di esempio, è necessario definire il Data Source Name (DSN). La sintassi in PostgreSQL prevede un prefisso pgsql: seguito da coppie variabile/valore per i seguenti possibili elementi:

  • host: nome dell’host, indirizzo IP oppure directory per la socket locale Unix;
  • port: porta del server PostgreSQL (di default 5432);
  • dbname: nome del database;
  • user: nome dell’utente per la connesione al database;
  • password: relativa password;

Il DSN per l’esempio risulta pertanto essere:


pgsql:host=localhost port=5432 dbname=pdo user=pdo password=pdo

La connessione avviene tramite la creazione di un oggetto PDO, specificando un DSN:


$dsn = 'pgsql:host=localhost port=5432 dbname=pdo user=pdo password=pdo';
$connection = new PDO($dsn);

Il primo vantaggio dell’utilizzo di PDO che si evince subito è l’approccio Object Oriented. In caso di errore, il costruttore della classe PDO lancia una eccezione PDOException. Includere il codice all’interno di blocchi try/catch semplifica molto la gestione degli errori.

Per maggiori informazioni: Costruttore classe PDO.

Inserimento di record

PDO mette a disposizione il metodo prepare per la creazione delle query preparate (prepared statement). La funzione accetta una stringa (che può contenere dei parametri, solitamente identificati dal carattere ‘?’) e restituisce un oggetto di tipo PDOStatement.

In caso di utilizzo di parametri, questo possono essere associati a variabili locali, sgravando pertanto il programmatore dalle operazioni di escaping che spesso costituiscono fonte di problemi. Ciò è possibile utilizzando il metodo bindParam della classe PDOStatement.


$stmt = $connection->prepare('INSERT INTO bands (band_name) VALUES (?)');
// Inserisce la prima band
$band = 'Dave Matthews Band';
$stmt->bindParam(1, $band, PDO::PARAM_STR);
// 1: il primo parametro nella query preparata
// $band: la variabile che contiene il valore da passare alla
query come primo parametro
// PDO::PARAM_STR: informa PDO che la variabile band deve
essere inserita nel database come stringa
$stmt->execute();

Selezione di record

Come nel caso dell’inserimento, PDO mette a disposizione la funzione prepare per l’esecuzione di query preparate (la cosa è estremamente utile nel caso di parametri nella condizione WHERE della query SELECT).

Tuttavia, torneremo con maggior dettaglio su questo argomento quando tratteremo i bytea (per usare une semplificazione, i campi blob inline di PostgreSQL). In questa sede copriremo il semplice metodo query della classe PDO, con il seguente esempio:


$results = array();
$sql = 'SELECT* FROM bands';
foreach ($connection->query($sql) as $row) {
$results['id']= $row;
}

Conclusioni

Questa breve guida ha esposto un esempio di connessione a un database PostgreSQL utilizzando PDO e l’esecuzione di una istruzione INSERT e di una SELECT. L’esecuzione di istruzioni DELETE e UPDATE è molto semplice e può essere intuita facilmente. In uno dei prossimi articoli copriremo uno degli aspetti meno trattati dell’interfacciamento di PostgreSQL e PDO in PHP: l’inserimento e il recupero di campi di tipo bytea.

Se siete interessati a approfondire questo argomento, non esitate a contattarmi oppure a partecipare a uno dei corsi 2ndQuadrant su PHP.

]]>
https://blog.2ndquadrant.it/php_postgresql_pdo_1/feed/ 0