giovedì 30 ottobre 2008

Importazioni immagini in PostgreSQL: un semplice script shell

Qualche giorno fa mi sono trovato a dover inserire una serie di immagini di persone in un database aziendale, ovviamente facendo corrispondere ciascuna persona alla propria immagine. Siccome il software che sto sviluppando non permette (ancora) di associare ad una persona la propria immagine, mentre consente di visualizzarla, ho deciso di caricare le immagini da linea di comando. Il problema era come mappare ogni immagine con la relativa persona. Purtroppo le immagini erano tutte nominate nella forma nome_cognome, e quindi l'unica strada era quella di sfruttare i relativi dati nel database. Ovviamente questo rischia di creare problemi in casi di omonimia, ma dopotutto è più rapido correggere alcune immagini sbagliate che inserirle una per una a mano!
Ho quindi creato il seguente script shell che fa il lavoro sporco:

#!/bin/bash

SQL_FILE="immagini.sql"
echo "BEGIN;" > $SQL_FILE

for img in *.tif
do
echo "\t==== Processo immagine $img ==="
NAME=`basename $img .tif`
NAME=`echo $NAME | sed 's/_N//;'`
NAME=`echo $NAME | sed 's/_B//;'`
NAME=`echo $NAME | sed 's/_[1-9]//;'`
NAME=`echo $NAME | tr [:upper:] [:lower:]`

echo "=> $NAME"
FILE_PNG=$NAME.png
FILE_PNG_1=$NAME_1.png

# conversione immagine
if [ ! -f $FILE_PNG ]
then
convert $img -quality 100 $FILE_PNG_1
convert $FILE_PNG_1 -resize 30% $FILE_PNG
fi

# estraggo nome e cognome
sql_surname=`echo $NAME | awk -F_ '{print $1;}'`
if [ -z "$sql_surname" ]
then
sql_surname="XXX"
fi

sql_name=`echo $NAME | awk -F_ '{print $2;}'`
if [ -z "$sql_name" ]
then
sql_name="YYY"
fi

CURRENT_DIR=`pwd`

echo -en "UPDATE person SET image = lo_import('$CURRENT_DIR/$FILE_PNG') WHERE " >> $SQL_FILE
echo -en " (lower(name)='$sql_name' AND lower(surname)='$sql_surname') " >> $SQL_FILE
echo -en " OR " >> $SQL_FILE
echo -en " (lower(surname)='$sql_surname' AND (SELECT COUNT(surname) FROM person WHERE lower(surname)='$sql_surname') = 1 )" >> $SQL_FILE
echo ";" >> $SQL_FILE

done


echo -en "\n\nCOMMIT;\n" >> $SQL_FILE

Come si può notare prima faccio un po' di pulizia sul nome del file (le immagini erano tutte .tif) e ottengo la stringa nome_cognome, e procedo ad una conversione nel formato richiesto dalla mia applicazione (png). Successivamente estraggo i singoli pezzi (nome e cognome) e costruisco una stringa di comando SQL per l'update di un campo blob (image) della tabella corrispondente (person). La query SQL effettua un update dove trova corrispondenza di nome e cognome o dove trova anche solo il cognome (a patto che ve ne sia solo uno). Tutte le query SQL vengono salvate in un file che viene poi lanciato da un terminale psql. Da notare che tutti gli inserimenti avvengono all'interno di una transazione, per evitare problemi di incoerenza (o si caricano tutte le immagini o nessuna).

Nessun commento: