sábado, 28 de julio de 2007

Importar datos externos a nuestra base de datos PostgreSQL mediante un script PHP

Hola a todos, este documento bien podria ser la continuación del documento anterior "Importar datos externos a nuestra base de datos PostgreSQL mediante COPY" pero ahora nos toca usar PHP para la importación de datos CSV hacia nuestra querida base de datos PostgreSQL.

Primero que nada empezemos por definir nuestra tabla que contendra los datos. La tabla tiene las siguientes caracteristicas para el ejemplo en cuestion:

Tabla «public.clientes_csv»
Columna | Tipo | Modificadores
---------------------+------------------------+---------------
id | integer |
rfc | character varying(15) |
nombre_razon_social | character varying(80) |
direccion | character varying(120) |
telefonos | character varying(50) |

sicodelico=>


Y ahora pasamos a mostrar un fragmento del archivo de excel con los datos a importar.



Guardamos el archivo para excel en formato CSV, quedandonos un archivo de texto plano en formato ascii y separado por comas. Es vital recordar que debemos eliminar los encabezados o datos que no deseemos importar a nuestra base de datos.

El archivo quedaria de la siguiente forma:


289,"ROAB","ABIGAIL ROCHA","MIRAMONTES","4554-4455"
311,"AHE821025DLA","ABUD HERMANOS S.A DE C.V.","SANTO DEGOLLADO 895 TEQISQUIAPAN SAN LUIS POTOSI","6766-7788"
26,"MBA831017P83","ACABADOS CONTEMPORANEOS","AV.DIVICION DEL NORTE #2001 COLONIA SANTA CRUZ ATOYAC DELEGACION BENITO JUAREZ","5677-5644"
50,"ASH020827694","ACABADOS SHUMA S.A DE C.V","25 PONIENTE 3513 BELICIARIO DOMINGEZ PUEBLA PUEBLA","2345-1033"
38,"AUHY760723CJA","AGUILERA HERNANDEZ YANET","AV.ERMITA IZTAPALAPA #655 PROGRESO DEL SUR IZTAPALAPA MEX.DF","1234-4567"
354,"MAROAA","ALAN AXEL MARIN ROBLES","VENDEDOR DE DELTA","3458-4564"
326,"ABC051019AX6","ALBERCAS BOMBAS Y CALENTADORES S.A DE C.V.","TANKAH MZA 11 LOTE 16 SMZA 27 POR AV. BENITO JUAREZ CANCUN Q.ROO","1234-5676"
41,"BOMA720502825","ALEJANDRA BOLAÑOS MORALES","LIBERTAD #58 LOCAL 4 Y 5 SAN SIMON TICUMAC DEL. BENITO JUAREZ","9890-5678"
207,"ERETQL","ALEJANDRA TERESA HERNANDEZ","CHALCO # 26 COLONIA EL CONDE NAUCALPAN EDO DE MEXICO","1234-5643"
212,"ONAL","ALEJANDRO GONZALEZ","VENTA DE CALENTADOR CON DESCUENTO","4532-2332"
344,"COCA601222LKG","ALEJANDRO SALVADOR COLINAS COSIO","TUXTLA GUTIERREZ CHIAPAS","2332-4554"


El archivo tiene el nombre de clientes.csv, ahora procedamos a mostrar el codigo PHP que nos servira para importarlo a nuestra base de datos mediante un formulario.


<?php
//
// Hecho Por: Julio Cesar Sánchez González - juliocesar_dark@hotmail.com
// Fecha: 27 / Jul / 2007.
//
// El programa se distribuye como tal, sin garantías de ningun tipo y
// esta liberado bajo la licencia publica general de GNU (GPL).
//
?>

<html>
<head>
<title>Importación de un archivo CSV de excel hacia
PostgreSQL</title>
</head>
<table>
<form action="" method="POST" enctype="multipart/form-data">
<tr>
<td>Subir archivo CSV:</td>
<td><input type="file" name="archivo_csv"
id='archivo'></td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" value="E N V I A R">
<input type="reset" value="C A N C E L A R">
</td>
</tr>
</form>
</table>
</body>
</html>

<?php

$file_upload = $_FILES["archivo_csv"]["name"];
$tmp_name = $_FILES["archivo_csv"]["tmp_name"];
$size = $_FILES["archivo_csv"]["size"];
$tipo = $_FILES["archivo_csv"]["type"];

if($size > 0){
echo "<h3>Archivo origen: $file_upload</h3>";
echo "<h3>Archivo destino: $tmp_name</h3>";
echo "<h3>Tamaño del archivo: ".($size/1024)." Kb.</h3>";
echo "<h3>Tipo MIME: $tipo</h3>";

// Comprobamos si el archivo a subir es CSV
if($tipo == "text/csv"){
$conex = "host=localhost port=5432 dbname=sicodelico \
user=juliocs password='foobar'";
$CONN = pg_connect($conex) or die ("Error en el socket \
de conexión");

echo "Conectando con la base de datos...<br>";
echo "Insertando los datos recuperados del archivo \
en la base de datos...<br>";

$fp = fopen($tmp_name, "r");

// Procesamos linea a linea el archivo CSV y
// lo insertamos en la base de datos
while($datos = fgetcsv ($fp, 1000, ",")){
$query = "INSERT INTO clientes_csv (id, rfc, \
nombre_razon_social, direccion, \
telefonos) VALUES ('$datos[0]', '$datos[1]', \
'$datos[2]', '$datos[3]', '$datos[4]')";

//echo $query;

pg_query($CONN, $query);
}

pg_close($CONN);
}else{
echo "<h3>El formato para el archivo especificado \
no es válido.</h3>";
}
}
?>


Aqui tenemos una imagen del formulario en funcionamiento:



y esta seria la salida de un select en el monitor psql de postgres con los datos ya importados:



Creo que eso es todo por hoy, ademas que ya son las 2:18 de la mañana y aunque suelo trabajar de noche mañana tengo una cita de negocios. Una ultima cosa, el codigo PHP lo tuve que cortar con "\" diagonal invertida ya que no se apreciaba bien del todo por el ancho del blog :( .

Buenas noches a todos y hasta la proxima.

4 comentarios:

Amimusa MANoU dijo...

Hola amigo,

¿Has probado a importar datos con acentos?

fgetcsv tiene un bug y se trata que se come los acentos, por ejemplo si tuvieras una linea así:

ramón;600123123;España

Al tratarlo te tomaría esto

ramn;600123123;España

Es una cosa que he detectado y estoy tratando de solucionar. En la documentacion de PHP.net hay implementada una clase que trata correctamente los acentos. De momento estoy usando esa clase.

Amimusa MANoU dijo...

Hola de nuevo,

Me autocorrijo, el ejemplo que he puesto lo procesaría correctamente, pero si el acento está en el primer caracter es cuando se lo come.

Este es el CSV que paso:
Nombre;DNS1;DNS2;DNS3;DNS4;Desactivar redirección
ávila.com;15;16;;si
avíla.com;15;16;;si
avilá.com;15;16;;si
españa.com;15;16;;si
ramón.com;15;16;;si
dominio.com;15;16;;no
kelme.es;15;15;;no

... y esto unos print_r() de cada linea:

Array ( [0] => Nombre [1] => DNS1 [2] => DNS2 [3] => DNS3 [4] => DNS4 [5] => Desactivar redirección )

Array ( [0] => vila.com [1] => 15 [2] => 16 [3] => [4] => si )

Array ( [0] => avíla.com [1] => 15 [2] => 16 [3] => [4] => si )

Array ( [0] => avilá.com [1] => 15 [2] => 16 [3] => [4] => si )

Array ( [0] => españa.com [1] => 15 [2] => 16 [3] => [4] => si )

Array ( [0] => ramón.com [1] => 15 [2] => 16 [3] => [4] => si )

Array ( [0] => dominio.com [1] => 15 [2] => 16 [3] => [4] => no )

Array ( [0] => kelme.es [1] => 15 [2] => 15 [3] => [4] => no )

chicaker dijo...

Hola que tal me gustaría saber si este ejemplo que publicaste se pueden implementar con un UPDATE en vez de un INSERT. Esta muy bueno tu ejemplo

chicaker dijo...

Hola que tal me gustaría saber si este ejemplo que publicaste se pueden implementar con un UPDATE en vez de un INSERT. Esta muy bueno tu ejemplo

Bahia desde el balcon...

Bahia desde el balcon...
Ixtapa Zihuatanejo