2012-07-12 34 views
20

Tengo un pequeño problema tratando de importar datos de un archivo CSV y tengo un par de preguntas que aún no he podido resolver.Importación de datos CSV usando PHP/MySQL

En primer lugar aquí está mi código para ayudar a poner las cosas en perspectiva (arreglado, en un poco, la eliminación de CSS y la conexión DB):

<body> 
<div id="container"> 
<div id="form"> 

<?php 
$deleterecords = "TRUNCATE TABLE tablename"; //empty the table of its current records 
mysql_query($deleterecords); 

//Upload File 
if (isset($_POST['submit'])) { 

    if (is_uploaded_file($_FILES['filename']['tmp_name'])) { 
     echo "<h1>" . "File ". $_FILES['filename']['name'] ." uploaded 
successfully." . "</h1>"; 
     echo "<h2>Displaying contents:</h2>"; 
     readfile($_FILES['filename']['tmp_name']); 
    } 

    //Import uploaded file to Database 
    $handle = fopen($_FILES['filename']['tmp_name'], "r"); 

    while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) { 
     $import="INSERT into importing(text,number)values('$data[0]','$data[1]')"; 

     mysql_query($import) or die(mysql_error()); 
    } 

    fclose($handle); 

    print "Import done"; 

//view upload form 
} else { 

    print "Upload new csv by browsing to file and clicking on Upload<br />\n"; 

    print "<form enctype='multipart/form-data' action='upload.php' method='post'>"; 

    print "File name to import:<br />\n"; 

    print "<input size='50' type='file' name='filename'><br />\n"; 

    print "<input type='submit' name='submit' value='Upload'></form>"; 

} 

?> 

</div> 
</div> 
</body> 

Es básicamente una adaptación de un ejemplo que he encontrado después de muchos muchos intentos en varios métodos.

Mi CSV tiene dos columnas de datos, siendo el primero el texto y la segunda es enteros La tabla en la base de datos también tiene dos columnas, la primera llamada "texto" y el segundo "número"

Así las preguntas que tengo son:

  1. el texto está cargando sólo está siendo visualizado como 0 en todos los campos y no estoy seguro de por qué
  2. estoy leyendo de datos que terminan encerrados en "", si eso sucede ¿cómo lo ordenaría?
  3. ¿cómo puedo ignorar las primeras líneas X del CSV para encabezados, etc.?
  4. ¿El formato de datos ha cambiado a lo largo de este proceso o está listo para usarlo en un gráfico? p.ej. ¿un decimal permanecería un decimal una vez colocado en la base de datos?

Creo que cubre todo, gracias de antemano por cualquier ayuda!

EDIT:

acaba de hacer una prueba de carga de 10.000 registros y tiene el error:

"Fatal error: El tiempo máximo de ejecución de 30 segundos superó"

alguna idea?

+2

Si va a cargar un archivo grande, también echar un vistazo a [carga de datos INFILE] (http://dev.mysql.com/doc/refman/5.1/en/load-data.html) como es MUCHO más rápido. 'LOAD DATA INFILE '/tmp/test.txt' EN TABLA prueba IGNORAR 1 LÍNEAS;' – Fluffeh

+0

@Fluffeh He intentado usar ese método, pero por alguna razón no funcionaría cuando lo incorporé a PHP. La velocidad definitivamente sería útil ya que será un archivo grande al final. – Pidge

+0

verifique mi respuesta actualizada. – jit

Respuesta

52

Me respondió una pregunta prácticamente idéntica, el otro día: Save CSV files into mysql database

MySQL tiene una característica LOAD DATA INFILE, lo que le permite importar un archivo CSV directamente en una sola consulta SQL, sin necesidad de que sea procesado en un bucle a través de su programa PHP en absoluto.

ejemplo simple:

<?php 
$query = <<<eof 
    LOAD DATA INFILE '$fileName' 
    INTO TABLE tableName 
    FIELDS TERMINATED BY '|' OPTIONALLY ENCLOSED BY '"' 
    LINES TERMINATED BY '\n' 
    (field1,field2,field3,etc) 
eof; 

$db->query($query); 
?> 

Es tan simple como eso.

Sin vueltas, sin problemas. Y mucho mucho más rápido que analizarlo en PHP.

página del manual de MySQL aquí: http://dev.mysql.com/doc/refman/5.1/en/load-data.html

Esperamos que ayuda

+0

Lo siento, ni siquiera me encontré en mi búsqueda de la web, ¡obviamente estaba buscando algo equivocado! Si usted podría tener un rápido vistazo para comprobar dónde lo he puesto yo sería buen señor eternamente agradecido :) (pastebin.com/e9wvsT4c) (guardar el texto de nuevo el correo basura por todas partes) – Pidge

+1

su código Pastebin parece como si tienes la idea correcta. Algunos errores todavía están presentes (por ejemplo '$ filename 'no está configurado), pero estoy seguro de que los solucionará con bastante facilidad. – SDC

+0

¡Bien, gracias por la ayuda! :) – Pidge

6
$i=0; 
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) { 
if($i>0){ 
    $import="INSERT into importing(text,number)values('".$data[0]."','".$data[1]."')"; 
    mysql_query($import) or die(mysql_error()); 
} 
$i=1; 
} 
+0

Eso corrigió el problema con el texto :) – Pidge

+0

Por curiosidad, ¿qué parte de esto hace que ignore la primera línea del CSV? – Pidge

+0

código diff con su código obtendrá su respuesta. aceptar la respuesta adecuada como respuesta aceptada – jit

1

letsay $ infile = a.csv // debe importarse el archivo.

class blah 
{ 
static public function readJobsFromFile($file) 
{    
    if (($handle = fopen($file, "r")) === FALSE) 
    { 
     echo "readJobsFromFile: Failed to open file [$file]\n"; 
     die; 
    } 

    $header=true; 
    $index=0; 
    while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) 
    { 
     // ignore header 
     if ($header == true) 
     { 
      $header = false; 
      continue; 
     } 

     if ($data[0] == '' && $data[1] == '') //u have oly 2 fields 
     { 
      echo "readJobsFromFile: No more input entries\n"; 
      break;       
     }    


     $a  = trim($data[0]); 
     $b = trim($data[1]);     





     if (check_if_exists("SELECT count(*) FROM Db_table WHERE a='$a' AND b='$b'") === true) 
     { 

       $index++; 
      continue;  
     }    

     $sql = "INSERT INTO DB_table SET a='$a' , b='$b' "; 
     @mysql_query($sql) or die("readJobsFromFile: " . mysql_error());    
     $index++; 
    } 

    fclose($handle);   
    return $index; //no. of fields in database. 
} 
function 
check_if_exists($sql) 
{ 
$result = mysql_query($sql) or die("$sql --" . mysql_error()); 
if (!$result) { 
    $message = 'check_if_exists::Invalid query: ' . mysql_error() . "\n"; 
    $message .= 'Query: ' . $sql; 
    die($message); 
} 

$row = mysql_fetch_assoc ($result); 
$count = $row['count(*)']; 
if ($count > 0) 
    return true; 
return false; 
} 

$infile=a.csv; 
blah::readJobsFromFile($infile); 
} 

Espero que esto ayude.

2
set_time_limit(10000); 

$con = mysql_connect('127.0.0.1','root','password'); 
if (!$con) 
    { 
    die('Could not connect: ' . mysql_error()); 
    } 

mysql_select_db("db", $con); 

$fp = fopen("file.csv", "r"); 

while(!feof($fp)) { 
    if(!$line = fgetcsv($fp, 1000, ';', '"')) { 
    continue; 
    } 

    $importSQL = "INSERT INTO table_name VALUES('".$line[0]."','".$line[1]."','".$line[2]."')"; 

    mysql_query($importSQL) or die(mysql_error()); 

} 

fclose($fp); 
mysql_close($con); 
+0

@Pidge "Acabo de hacer una prueba de 10.000 registros cargados y obtuve el error ..." Con este script he importado más de 1M de CSV. Debería funcionar para usted. – dzeno

0

Creo que las cosas principales a tener en cuenta acerca de analizar CSV es que sigue algunas reglas simples:

a) se trata de un archivo de texto para fácilmente abierto b) cada fila está determinada por un final de línea \ n así que divida la cadena en líneas primero c) cada fila/línea tiene columnas determinadas por una coma así que divida cada línea para obtener una matriz de columnas

have a read of this post para ver lo que estoy hablando

en realidad es muy fácil de hacer una vez que tienes el truco y es muy útil.

0

base de datos de conexion:

try { 
     $conn = mysqli_connect($servername, $username, $password, $db); 
     //echo "Connected successfully"; 
    } catch (exception $e) { 
     echo "Connection failed: " . $e->getMessage(); 
    } 

código para leer CSV archivo y subir a la tabla de la base de datos.

$file = fopen($filename, "r"); 
      while (($getData = fgetcsv($file, 10000, ",")) !== FALSE) { 
       $sql = "INSERT into db_table 
        values ('','" . $getData[1] . "','" . $getData[2] . "','" . $getData[3] . "','" . $getData[4] . "','" . $getData[5] . "','" . $getData[6] . "')"; 
       $result = mysqli_query($conn, $sql); 
       if (!isset($result)) { 
        echo "<script type=\"text/javascript\"> 
          alert(\"Invalid File:Please Upload CSV File. 
          window.location = \"home.do\" 
          </script>"; 
       } else { 
        echo "<script type=\"text/javascript\"> 
         alert(\"CSV File has been successfully Imported.\"); 
         window.location = \"home.do\" 
        </script>"; 
       } 
      } 
      fclose($file); 
Cuestiones relacionadas