Всем доброго времени суток!
Будьте добры помогите советом.
Вытягиваю данные из файла csv и подготавливаю node к записи в БД посредством node_save
вот часть кода:
<?php
$node=new stdClass();
$node->title=iconv("CP1251","UTF-8",$line[2]);
$node->type="product";
node_object_prepare($node);
$node->model=$line[1];
$node->field_height=array(array("value" => $line[20]));
$node->field_width=array(array("value" => $line[21]));
$node->field_length=array(array("value" => $line[22]));
$node->field_discount=array(array("value" => $line[23]));
$node->body=iconv("CP1251","UTF-8",$line[24]);
$node->language = "ru";
for($i=0;$i<count($terms);$i++)
$node->field_catalog[]["value"]=$terms[$i];
$node->field_image_cache[0]=(array)$file;
node_save($node);
?>
всё работает, всё добавляется но, вылетает maximum allowed memmory ... , памяти 128, я так понимаю для среднего сайта это вполне нормально.
Если смотреть диспетчер памяти, то выделение идет чуть ли не по 1МБ на каждую добавленную ноду (соот-но 155 нод и память выделенная скрипту кончилась ).
это понятно, что пока нода сохранится она вызовет хуки всех модулей, чтобы добавили в нее данные.
Может кто сталкивался с такой проблемой? как ее обойти? в файле порядка 5000 строк.
Может делать вставку в БД вручную. минуя node_save?
Комментарии
Всегда хотел поэкпериментировать на эту тему, попробуй после
Вызвать
Чисто для спортивного интереса
тоже пришла подобная мысль в голову, после обноружения этой проблемы:
вот:
<?php
unset($node);
unset($line);
unset($file);
?>
ни х.. не помогает, как было так и осталось, добовляет ровно 155 нод.
ну, добавит больше если убрать термины и изображения
<?php
for($i=0;$i<count($terms);$i++)
$node->field_catalog[]["value"]=$terms[$i];
$node->field_image_cache[0]=(array)$file;
?>
если добавлять только ноду, без доп. полей, то максимум 1000 с небольшим
блин, причем памяти дал скрипту порядком, чего нельзя позволить на рабочей площадке сайта.
Файл .csv сразу в массив загоняете, или по циклу по строке читаете?
по циклу, по строке. но дело тут не в этом, если выводить файл через echo или print_r (без node_save), то он полностью выводится, и довольно таки быстро, файл порядка 1.5 мб
хм, наврал, файл не больше 1 МБ, а точнее 774 кб
Тогда ещё идея, делать не в виде модуля, а в виде отдельного файла с подключением bootstap.inc и ТОЛЬКО нужных модулей.
да, надо будет попробовать.
а можно еще после импортирования 100 нод запоминать строку где был последний импорт, выдать информацию пользователю и перенаправить на урл дальнейшего импорта, вобщем буду разбираться.
Дык, зачем показывать пользователю, сохранять в переменную в БД, слава богу сие может, а потом с неё начинать
я просто сразу вспомнил одну весч:
в битриксе есть такая возможность как быкап данных, так вот, там этот быкап выполняется довольно такие большой промежуток времени и обновляется каждые 15 секунд, плюс в том что пользователь видит, что процесс идет. ну и делается это все через ajax, интересно как они сбрасывают этот буфер и очищают память, ведь должен же быть выход
Нет, ну если хочется, то можно и прогресс бар сделать красивый, но зачем лишний геморой, особенно в экспериментах?
смотрю в будущее, делать все равно придется, это уже не эксперименты
Нечто подобное выполнял на локалхосте через node_import. Лимит по времени выставлял на 15 минут, и несколько тысяч нод уходили без проблем. Утечек памяти по мегабайту на ноду не наблюдал.
Да вот мне тоже странно. Занимался миграцией сайта с ВП на друпал, перенёс около 10 000 нод, с ССК, всё как надо. И тоже таких проблем не замечал
юзайте http://api.drupal.ru/api/group/batch/6
Да так, batch апи есть, и про аякс верно (им нужно вызывать импорт по одному файлу, то есть по порядку - скрипт вызовется столько раз сколько файлов/нод), но batch api как раз для этого и сделано.
Экспериментальным путем было установлено, что затык происходит при импорте терминов таксономии:
<?php
for($i=0;$i<count($terms);$i++)
$node->field_catalog[]["value"]=$terms[$i];
?>
если убрать импорт терминов, то за 160 секунд импортируется порядка 1143 нод против 155 при включенном, огромных утечек памяти не обнаружено, да httpd процесс пожирает память но не по 1 мб, а где то по 200кб.
мда, буду думать как быть с терминами, отключать модули поочередно и тестировать? :-(((
ну и конечно благодарю за совет и batch, тоже буду пробовать
я недавно эксперимент проводил:
Импорт из csv файла в таблицу бд с помощью INSERT сравнивал с созданием нод на основе ттого же csv файла c помощью node_save().
За 60сек в таблицу с помощью инсерт импортировалось около 73 тысячи записей, а вот нод за теже 60сек создалось всего около 250 штук.
если тест будет учитывать добавление данных в таблицы CCK, file, и выставлял связь добавленных нод с терминами,IMHO результат будет более объективен.
так для того и тест был, что бы узнать долю того о чем вы говорите