Вопрос Способы обновления данных через API

Тема в разделе "Создание расширений для Joomla", создана пользователем DKraev, 07.02.2014.

  1. DKraev
    Offline

    DKraev <i>(aka gft)</i> => Cпециалист <=

    Регистрация:
    16.08.2008
    Сообщения:
    1 627
    Симпатии:
    219
    Пол:
    Мужской
    Приветствую, друзья.

    Пишу расширение для seblod. В двух словах: есть сайт агентства недвижимости. Есть API, с которого вытягиваем в нашу базу все данные по объектам. Количество объектов - 2100 шт. Все работает через крон, либо админку, если необходимо сделать синхронизацию вручную.

    Вопрос. Как лучше синхронизировать данные. Кто какие способы использует? Я думал сначала очищать таблицу полностью, потом загонять все объекты, которые пришли с АПИ по нашему запросу. Однако данный способ не очень удобен. Добавление объектов занимает минут 20. Соответственно, какое-то время сайт будет недоступен, что не есть хорошо.

    Собственно, нет проблем сделать сравнение по ID - это будет и быстрее и не возникнет проблем с недоступностью сайта, однако тут есть момент, который мне непонятен. Как удалить данные из нашей базы, которых на текущий момент уже нет в API?

    К примеру производим первичное наполнение. У нас есть три объекта с ID 1,2,3
    Через час производим синхронизацию. Объект с id 3 был удален и в API не присутствует, но появился объект с ID 4. C тем чтобы добавить 4 - проблем нет. А вот как удалить из нашей базы ID 3?

    Получать весь массив ID и сравнивать с имеющимся в базе?
     
  2.  
  3. DKraev
    Offline

    DKraev <i>(aka gft)</i> => Cпециалист <=

    Регистрация:
    16.08.2008
    Сообщения:
    1 627
    Симпатии:
    219
    Пол:
    Мужской
    Сижу, думаю. Может сначала делать добавление объектов во временную таблицу, а после окончания импорта, очищать рабочую и тут же заливать данными из времянки?
     
  4. DKraev
    Offline

    DKraev <i>(aka gft)</i> => Cпециалист <=

    Регистрация:
    16.08.2008
    Сообщения:
    1 627
    Симпатии:
    219
    Пол:
    Мужской
    woojin, спасибо, но все ссылки что ты дал относятся к репликации. Т.е. подразумевается две БД на разных серверах, между которыми необходимо сделать синхронизацию.

    Проблема в том, что я не имею доступа к материнскому серверу и БД, соответственно. Имею лишь полученные данные по API в формате JSON. Т.е. я сначала получаю через API требуемые данные, а потом их записываю себе в базу.
     
  5. AKopytenko
    Offline

    AKopytenko Russian Joomla! Team Команда форума

    Регистрация:
    01.09.2011
    Сообщения:
    1 963
    Симпатии:
    168
    Пол:
    Мужской
    =O
    Я может чего не так понял... Я компонент под Virtuemart писал для работы с выгрузками из базы поставщиков - 6300 товаров (название, описание, картинка, артикул, кол-во в наличии, цена, производитель + настраиваемые поля), загрузка занимала совсем немного времени.
    Правда работает только вручную, через CRON ничего не делал пока ещё...
    Ты чего выгружаешь то по недвижимости? откуда там такие объёмы то могут быть?

    Так а тебе что нужно сделать? Я тоже сначала подумал, что обновить содержимое одной базы на основании другой.
     
  6. DKraev
    Offline

    DKraev <i>(aka gft)</i> => Cпециалист <=

    Регистрация:
    16.08.2008
    Сообщения:
    1 627
    Симпатии:
    219
    Пол:
    Мужской
    Доступа к родительской БД у меня нет. Я обновляю через API - http://api.recrm.ru/doc/

    Сначала прогоняю поиском, вычисляя все ID объектов компании - один запрос к API. Затем по каждому ID в цикле получаю полную информацию по объекту - это еще 2100 запросов к API. Все это пишу в три своих таблицы БД, выполняя три insert.

    Сейчас сделал реализацию через временную таблицу. Т.е. сначала пишу все объекты во времянку, после окончания импорта, очищаю рабочие таблицы и копирую все данные с времянки (вот этот запрос занимает меньше секунды). После чего времянку тоже очищаю.

    Ранее не сталкивался с обновлением такого большого объема информации через API, поэтому решил поинтересоваться, может кто подскажет более правильные решения.
     
  7. woojin
    Offline

    woojin Местный Команда форума => Cпециалист <=

    Регистрация:
    31.05.2009
    Сообщения:
    3 206
    Симпатии:
    334
    Пол:
    Мужской
    есть ещё одно решение, возможно тебе оно подойдёт больше
    можно после получения всех данных через API сформировать запрос на добавление в твою таблицу/таблицы
    или прямо в процессе получения данных формировать запрос (он же INSERT)

    после полной отработки API чистишь свою таблицу и запускаешь сформированный запрос, тут может возникнуть только одна проблема очень долгое время исполнения, для этого можно новый запрос поделить на части и запускать скрипт (подразумевается php скрипт) добавления несколько раз, пока все данные не будут внесены

    примерно также работает Akeeba, только там ещё и JS подключается для отображения прогресса

    P.S. если много текстовых полей то обязательно ставь на них индексацию FUULTEXT - работать будет вообще моментально при поиске

    P.P.S. как сделать перезапуск php скрипта из php скрипта я ещё не освоил, задач таких не было, но в и-нете где то натыкался на такую штуку, что то там связано с FOPEN(тут адрес этого же скрипта внутри которого идёт обработка GET и POST данных, с передачей параметров перезапуска). так что пробуй - ни чем больше помочь не могу
     
  8. AKopytenko
    Offline

    AKopytenko Russian Joomla! Team Команда форума

    Регистрация:
    01.09.2011
    Сообщения:
    1 963
    Симпатии:
    168
    Пол:
    Мужской
    Трррррр, 2100 запросов - это полный пипец.
    Не лучше будет собрать в цикле строку запроса (обычную строку через .= ) и затем отправить его один раз?

    P.S.: woojin, пока писал уже опередил с предложением)) ну в общем да, то же самое по сути....
     
    DKraev нравится это.
  9. DKraev
    Offline

    DKraev <i>(aka gft)</i> => Cпециалист <=

    Регистрация:
    16.08.2008
    Сообщения:
    1 627
    Симпатии:
    219
    Пол:
    Мужской
    Ну большого пипеца я не вижу, если материнский сервак вывозит это. Что касается запросов - один запрос - один ответ - один объект. Другой реализации в описании API я не нашел.

    В общем сделал так. PHP обработчик зациклен сам на себя, обрабатывая по 10 объектов за раз. Данные пишутся во временную таблицу. Скриптом сделан прогресс, который подсчитывает количество вставленных объектов. После того, как php отработал все объекты, он убивается и вызывает функцию копирования из времянок в рабочие таблицы, предварительно очистив их. Процесс копирования занимает меньше секунды.

    Все отрабатывает коррекно.

    Всем спасибо!

    p/s: woojin, друже, не дает форум тебя плюсануть :) Коварный! :) Спасибо тебе!
     
  10. Hishchnik
    Offline

    Hishchnik Недавно здесь

    Регистрация:
    23.12.2014
    Сообщения:
    12
    Симпатии:
    0
    Пол:
    Мужской
    а не проще их ID записывать к себе в базу как например product_id,
    при получении новой партии формировать строку ID
    у вас же все равно при распарсивании массив например $this->result;
    Код (PHP):
    1. $my_id = implode(',', $this-result->id);
    2. /*Дальше уже удалить из базы те "product_id" которых нет в массиве*/
    3. $query = "  DELETE  FROM #__my_product WHERE  product_id NOT IN  (" . $my_id . ")";

    сделать выборку product_id
    и в цикле удалить существующие в базе элементы массива, и оставшиеся(если есть) записать в базу

    Вариант?
     
    Последнее редактирование: 23.12.2014
  11. DKraev
    Offline

    DKraev <i>(aka gft)</i> => Cпециалист <=

    Регистрация:
    16.08.2008
    Сообщения:
    1 627
    Симпатии:
    219
    Пол:
    Мужской
    Проблема, в принципе, давным давно решена и мой вариант успешно работает уже почти год, два раза в день обновляя информацию.

    Но ваш вариант имеет место быть. Но опять же с ограничением. Если брать вариант когда нам надо добавлять новые объекты и удалять пустые - это отработает. Но как быть с обновлением данных? Допустим у объекта поменялась цена и описание? Сравнивать то что имеется с тем что приходит и перезаписывать? В принципе, можно. Можно также тупо перезаписывать имеющиеся объекты. Но я писал, что апи достаточно тугодумный, работает вся конструкция долго, и писать сразу в базу неправильно с точки зрения целостности данных. Произойдет сбой во время импорта. Благо если все нормально. А если отвалился сайт? Опасаюсь за нервы клиента в данном случае ))

    Хотя может я и не прав. Но вариант с временной таблицей показался мне наиболее безопасным. Даже если что-то пошло не так - не беда. Времянка не участвует в работе сайта. При следующем импорте все будет гуд. Дополнительно я добавил оповещение на мыло, если происходит сбой, т.е. клиент может через некоторое время зайти на сайт и запустить импорт уже вручную.
     

Поделиться этой страницей

Загрузка...