Asynchronus- PHP Загрузить огромные данные CSV в MYSQL - PullRequest
0 голосов
/ 14 января 2020

Я пытался загрузить около 20 000 строк CSV в SQL, используя метод asyn c, ссылаясь на этот пост:

Как импортировать огромный CSV-файл с 200,00 строками в MySQL (асинхронный и быстрый)?

Сценарий уже запущен и успешен, когда я загружаю 10000 данных, но когда я зарегистрировался в базе данных, я обнаружил, что были только половина строк (5000 строк) Поставлен . Я пытался изменить $ batchsize с 1000 на 100, только 9400 строк вставлено вместо якобы 10000 строк

вот мой текущий код:

index. php:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>csv upload</title>
</head>
<body>
    <form action="upload.php" method="post" enctype="multipart/form-data">
        <input type="file" name="csv" value="" />
        <input type="submit" name="submit" value="Save" />
    </form>
</body>
</html>

загрузка. php:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.1/jquery.js"></script>

<script>
//Declaration of function that will insert data into database
 function senddata(filename){
        var file = filename;
        $.ajax({
            type: "POST",
            url: "senddata.php",
            data: {file},
            async: true,
            success: function(html){
                $("#result").html(html);
            }
        })
        }
</script>

<?php

$batchsize = 100; //split huge CSV file by 1,000, you can modify this based on your needs

if($_FILES['csv']['error'] == 0){

    $name = $_FILES['csv']['name'];
    $ext = explode(".", $name);
    $ext = $ext[1];
    $tmpName = $_FILES['csv']['tmp_name'];

    if($ext === 'csv'){ //check if uploaded file is of CSV format

        if(($handle = fopen($tmpName, 'r')) !== FALSE) {

            set_time_limit(0);
            $row = 0;

            while(($data = fgetcsv($handle)) !== FALSE) {

                //splitting of CSV file :
                if ($row % $batchsize == 0):

                    $file = fopen("minpoints$row.csv","w");

                endif;

                $csv[$row]['col1'] = $data[0];
                $csv[$row]['col2'] = $data[1];
                $min = $data[0];
                $points = $data[1];
                $json = "'$min', '$points'";
                fwrite($file,$json.PHP_EOL);

                //sending the splitted CSV files, batch by batch...
                if ($row % $batchsize == 0):

                    echo "<script> senddata('minpoints$row.csv'); </script>";

                endif;
                $row++;

            }

            fclose($file);
            fclose($handle);

        }
    } else {

        echo "Only CSV files are allowed.";

    }
    //alert once done.
    echo "<script> alert('CSV imported!') </script>";
} ?>

senddata. php:

<?php
include('config.php');
$data = $_POST['file'];
$handle = fopen($data, "r");
$test = file_get_contents($data);
// print_r($test);die;
if ($handle) {
    $counter = 0;
    //instead of executing query one by one,
    //let us prepare 1 SQL query that will insert all values from the batch
    $sql ="INSERT INTO table_test(name,contact_number) VALUES ";
    while (($line = fgets($handle)) !== false) {
      $sql .= "($line),";
      $counter++;
    }
    $sql = substr($sql, 0, strlen($sql) - 1);
     if ($conn->query($sql) === TRUE) {
    } else {
    }
    fclose($handle);
} else {  
} 
//unlink CSV file once already imported to DB to clear directory
unlink($data);
?>

Мои цели:

  1. Асинхронно загружать огромные данные CSV с полными данными
  2. Чтобы понять эти коды: -> fwrite ($ file, $ json .PHP_EOL); и -> senddata ('minpoints $ row.csv'); ;

1 Ответ

1 голос
/ 15 января 2020

Таблица table_test имеет столбец NOT NULL, а CSV имеет значения NULL в некоторых случаях, и поэтому не вставляется.

Вы можете сделать name и contact_number NULL , с ALTER TABLE table_test MODIFY name your-type(your-number); Столбцы обнуляются по умолчанию. Пока столбец не объявлен как UNIQUE или NOT NULL, проблем быть не должно.

@ owf: - спасибо, после того как я изменил таблицу структуры, она работает отлично , В любом случае, у вас есть идея, как пропустить первый ряд (заголовок)? Я попытался использовать, если $ counter> 0 в senddata. php, но он пропускает каждый первый счетчик каждой партии

R : Прежде всего, вам нужно $flag первый проанализированный csv , чтобы знать, что он идет с первым пропускаемым рядом. Добавьте переменную в ajax, которая проверяет, является ли первый зарегистрированный csv . Итак, en ajax.php вы знаете, является ли csv первым или нет, основываясь на этом методе, вы можете пропустить первый ряд первого пакетного csv

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...