Импорт больших SQL-дампов через PHP
27 мая 2011
Основная проблема при импорте большого SQL-дампа — нехватка памяти при чтении всего дампа. Решение очевидно: грузить в память только то, что нужно в данный момент.
$f = @fopen("path/to/dump.sql", "r"); if($f) { $q = ''; while(!feof($f)) { // читаем построчно в буфер $q $q .= fgets($f); // пока не упрёмся в ; if(substr(rtrim($q), -1) == ';') { // выполяем запрос execute_sql($q); // обнуляем буфер $q = ''; } } }
Комментарии RSS по email OK
Консоль или sypex dumper Зачем "велик" то?
И код такой работать тоже не будет скорее всего. Нету гарантии что в 4кб попала целая строка
seocoder, например, если нужно сделать свой инсталлер для продукта. Не заставлять же пользователя ставить и использовать Sypex. Ограничение убрал.
Как-то ненадежно у вас это все, да и медленно будет. А если последовательность ";\n" встретится внутри какого-нибудь текстового поля? Я бы больше предпочел команду из консоли
либо если доступа к ней нет, то инструкцию LOAD DATA INFILE.
conf, если вообще нет доступа к
ssh
иexec
нельзя?Кстати, перенос строки в данных импорт не сломает. Вот
;
может.Выложу свои решения-ка... import.php:
export.php:
Работают безотказно. Лучше чем phpmyadmin. Даже когда все скрипты/проги не могут импортнуть/экспортнуть - эти скрипты справляется.
Максим, на большом дампе
file_get_contents
захлебнётся.Можно переделать на fopen, это всего лишь основа. Зато мой скрипт анализирует синтаксис sql файла. И всегда точно определяет запросы.
много велосипедов хороших и разных, чем консоль mysql не устраивает? это нормально работает и с 8 гб дампами mysql>use db; mysql>source file.sql;
Ужос ужос!
Как правильно заметили, ";" внутри данных ваш код поломают. Еще может попасться ";" внутри комментария (это, конечно, реже, но возможность есть). Да и freads лучше на fread() заменить наверное.
Решение от Максима еще куда ни шло, но нужно допилить для комментариев и для больших дампов (заменить file_get_contents и убрать strlen($dump) на каждой итерации как минимум)
Сергей #3, Если вы обладаете более лучшим решением, то покажите нам его. А про оптимизации я и так знаю.
Вы тут нас совсем за дурачков/идиотов принимаете с такими постами?))))
А по-моему хороший пост. Потому что: 1) не всегда есть доступ к phpmyadmin. 2) не всегда серверные решения работают корректно. Я именно по этим причинам и написал свой велосипед когда работал с рекламном агентстве и занимался сайтами. Когда подписан договор и уже пошел процесс работы ни принимающая/ни отдающая сторона не станет искать данные у человека который ответственен за доступы к панеле управления, и который, возможно, уже не работает в компании-заказчике.
Ниочем вообще. Синтаксис sql куда богаче, одним if-ом не обойтись. Даже если удастся правильно разбирать поток на наличие знака ";" это все равно ничего не гарантирует - в mysql можно вызвать SET DELIMITER.
Плюс ко всему, ну правда, в чем смысл? Почему так тянет на велосипеды? Делать такой код бессмысленно, тратите как свое время, так и время заказчика на пустую проблему - гораздо дешевле взять более правильный тариф или хостинг, чем пытаться писать неработоспособный код и поддерживать его.
Даже если есть необходимость, все можно сделать проще - вынести table definion в отдельный файл, table content - в другой, например формата csv - и это будет гарантированный результат работы, который можно покрыть тестами. Сделать аналогичное для sql92 хотяб куда сложнее.
Для sql используется простой лексический анализатор, мой скрипт импорта прекрасно распознает концы запросов, при этом не путая их с ; внутри строк...
Если слушать критику, тогда ни phpmyadmin, ни sypex dumper и ему подобные не нужны, так как заказчика можно убедить перейти на хороший хостинг с поддержкой ssh.
Такой вариант подходит только если к консоли нету доступа.
Реально бывают случаи, когда нет ни консоли, ни phpMyAdmin. Например, образовательным учреждениям бесплатно раздают убогие площадки для сайтов. В таких случаях я бы сам поставил phpMyAdmin и не парился.
Почему-то большинству не приходит в голову, что вариант чтения дампа скриптом всё-таки в некоторых случаях - единственное решение. Реальный пример:
Заказчик просит проработать оную возможность, т.к. хочет
Только указанный в посте вариант укакается при конструкции такого вида:
INSERT INTO TableName (...) VALUES (...),(...), ... ;
,где список содержимого состоит из многих полей. Т.е. сам ";" стоИт в самом конце и сводит на нет саму логику примера.
Было бы шикарно, если бы кроме критики еще и решение