Экспорт больших данных в сервер Yii Stuck для работы - PullRequest
0 голосов
/ 27 февраля 2019

Я работаю в Yii и хочу экспортировать большие данные приблизительно по 2 записи за один раз.Проблема в том, что когда я пытаюсь экспортировать данные, сервер перестает работать и зависает весь процесс в системе.Я должен убить все службы и перезапустить сервер снова, m Может кто-нибудь сказать мне соответствующий способ экспорта данных в CSV-файл.

$count = Yii::app()->db->createCommand('SELECT COUNT(*) FROM TEST_DATA')->queryScalar();
$maxRows = 1000:
$maxPages = ceil($count / $maxRows);

for ($i=0;$i<$maxPages;$i++)
{
$offset = $i * $maxRows;
$rows = $connection->createCommand("SELECT * FROM TEST_DATA LIMIT $offset,$maxRows")->query();
foreach ($rows as $row)
{
  // Here your code
}
}

1 Ответ

0 голосов
/ 27 февраля 2019

Может быть, это из-за обработки кода без закрытия сессии.Когда вы запускаете процесс и не закрываете сеанс, в период обработки кода вы не можете загрузить ни одну страницу сайта (в том же браузере) из-за сеанса (он будет занят).Это может быть принято как «зависание сервера», но сервер работает как надо.Вы можете проверить это, загрузив сайт в другом браузере, если он загружается, это означает, что процесс работает так, как и должно быть.

По моему опыту, я использовал таблицу для сохранения данных обработки (успешно обработанное смещение,last_iterated_time) и посмотреть текущее состояние обработки.Пример таблицы «processing_data» с переменными «id» (int), «stop_request» (tinyint, для остановки процесса, если 1 остановить итерацию), «offset» (int), «last_iterated_time» (datetime).Добавьте только одну запись в эту таблицу, и на каждой итерации проверяйте переменную stop_request, если она получает значение 1, вы можете прервать итерацию.И на каждой итерации вы можете сохранить текущее значение смещения в текущую дату и время.Делая это, вы можете остановить обработку и продолжить.

И вы можете использовать while (чтобы уменьшить использование памяти) для итерации без подсчета:

set_time_limit(0);
$offset=0;
$nextRow= $connection->createCommand("SELECT * FROM TEST_DATA LIMIT $offset, 1")->queryRow();

while($nextRow) {
    //Here your code

    $processingData= ProcessingData::model()->findByPk(1);
    $processingData->offset=$offset; 
    $processingData->last_iterated_time=new CDbExpression('NOW()');
    $processingData->save();
    if($processingData->stop_request==1) { break; }
    $offset++;
    $nextRow= $connection->createCommand("SELECT * FROM TEST_DATA LIMIT $offset, 1")->queryRow();
}
...