Добро пожаловать на сайт <БагБД>, где вы можете задавать вопросы о программировании и разработке на Битрикс и Битрикс24, и получать быстрые и квалифицированные ответы от профессионалов!

загрузка инфаблока из CVS в MySQL

00 голосов
5
код для автоматического добавления элементов пишу из файла CVS. использую LOAD DATA LOCAL INFILE. Данные инфоблока хранятся в 2 таблицы - b_iblock_element и b_iblock_element_prop_s16 (скопировал в отдельную таблицу для удобного написания кода добавления, добавятся будут свойства не массива, простые.) в первой каждому элементу добавленному автоматически присваивается ID, а свойства во второй таблице имеют столбик IBLOCK_ELEMENT_ID который и указывает от какого элемента эти свойства.
не могу решить задачу, как сделать что бы присваивались для одного элемента одинаковые ID и IBLOCK_ELEMENT_ID - если их уже прописать заранее то будет не уникально оно и тогда при добавлении элементов что нить затереться может.
Думал префикс добавлять, но ID не позволяет буквы.
тут код что набросать успел:

Код
<?
$host='localhost:31006'; // имя хоста (уточняется у провайдера)
$database='bitrix'; // имя базы данных, которую вы должны создать
$user='root'; // заданное вами имя пользователя, либо определенное провайдером
$pswd=''; // заданный вами пароль
 
$dbh = mysql_connect($host, $user, $pswd) or die("Не могу соединиться с MySQL.");
mysql_select_db($database) or die("Не могу подключиться к базе.");

=============== 8< =============== 8< =============== 8< =============
?>
спросил 17 Дек, 13 от hipiro (280 баллов)

5 Ответы

00 голосов
Что-то тут страшное и непонятное.
Читать можно через fgetcsv() или file() + explode().
Добавлять через CIblockElement::Add().
Для работы с базой следует пользоваться $DB->Query().
А можно поинтересоваться, зачем совпадение айдишников свойств и какая задача решается?
ответил 01 Март, 14 от Eddie (2,060 баллов)
00 голосов
Цитата
Что-то тут страшное и непонятное.

но работает быстро, сотые а иногда и тысячные секунды на запрос, даже возникают сомнения выполнился ли он, но проверяю - все добавлено в таблицы.
ID - в инфаблоках Битрикса у каждого инфаблока есть свой номер, он попорядку задается в таблице b_iblock_element (столбец ID) при добавлении новых строк-элементов. в этой же таблице хранится и название и анонс и детальный текст - все что стандартно присутствует в каждом элементе инфаблока. а вот свойства что можно еще самому добавлять (на вкладке свойства при настройке инфаблока)хранятся уже в отдельной таблице b_iblock_element_property (или b_iblock_element_prop_s16 в моем случае). Для того чтобы CMS определила к какому именно элементу относится свойство, в последней таблице есть столбец IBLOCK_ELEMENT_ID который и содержит ID своего хозяина. Как правило количество записей очень сильно не совпадет в этих двух таблицах (почему - это еще на 1 том сочинений...) поэтому идентифицировать свойство к хозяину по порядковому номеру свойства не получается. я рассматриваю код стандартного импорта из CVS ведь там это как то решено, но пока еще не нашел как происходит этот загадочный процесс. Возникают мысли использовать триггеры, но люди увидившие мне что то страшное рассказали чтоони очень тормозят запросы.

а по поводу
Цитата
`NAME`,`NAME`,`NAME`,`NAME`
так это запрос не позволяет использовать ,,,, или например ,'','','','', для пропуска значения в CVS файле.
ответил 20 Июнь, 14 от hipiro (280 баллов)
00 голосов
а задача какая - в 1С бухгалтерии по нажатию кнопки справочник (нужные элементы его) выгружаются в CVS, отсылаются на сервер и сохраняются локально и автоматически загружаются на сайт.
в данный момент выгрузка в CVS написана, файл по нажатию кнопки попадает на сервер, а его загрузка на сайт осуществляется уже вручную при помощи импорта CVS.
цель - достичь автоматизации: в обработке 1С после выгрузки файла будет запускается по ссылке PHP код с запросом и происходить загрузка файла в базы данных SQL
ответил 19 Окт, 14 от hipiro (280 баллов)
00 голосов
Если у вас элементов не сотни тысяч, не оптимизируйте скорость в ущерб гибкости и переносимости кода, особенно когда речь об инфоблоках 2.0. Выиграете немного, а получите кучу проблем с целостностью и переносимостью в дальнейшем, за что заказчик будет вас потом долго вспоминать. Битрикс практически не использует функционал реляционной модели в привычном виде, да и пользователь может изменить формат хранения данных иблока в любой момент, или там подключить функцию документооборота. И весь скрипт накроется.
Используйте CIBlockElement::Add, с обычной привязкой к элементам справочника 1с по гуиду XML_ID и свойствами в 'PROPERTY_VALUES'.
Подгружать свойства для созданных/существующих элементов из другой csv тоже можно по гуиду родительского элемента через 'PROPERTY_VALUES' в CIBlockElement::Update.
ответил 19 Фев, 15 от Eddie (2,060 баллов)
00 голосов
Код
<?
// подключение пролога
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/header.php");
?>

<?php
CModule::IncludeModule('iblock');
$row = 1; 
$handle = fopen ("C:/RABOTY.csv","r"); 
while ($data = fgetcsv ($handle, 10000, ";")) 
{ 
    $num = count ($data); 
    print "<p> $num полей в строке $row: <br>\n"; 
    $row++; 
    for ($c=0; $c < $num; $c++) 
    { 
       print $data[$c] . "<br>\n"; 
      
                $el = new CIBlockElement;
      $tempa = $data[$c];
      if($PRODUCT_ID = $el->Add($tempa))
        echo "New ID: ".$PRODUCT_ID;
      else
        echo "Error: ".$el->LAST_ERROR;
   } 
} 
fclose ($handle); 
?>
<?
// подключение эпилога
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/footer.php");
?>


ошибку выдает
Fatal error: Cannot create references to/from string offsets nor overloaded objects in C:\Program Files\Bitrix Environment\www\bitrix\modules\iblock\classes\general\iblockelement.php on line 2899.

2899 строчка у меня содержит:

Код
2895 if(!$this->CheckFields(&$arFields) || strlen($strWarning))
2896      {
2897         $this->LAST_ERROR .= $strWarning;
2898         $Result = false;
2899         $arFields["RESULT_MESSAGE"] = &$this->LAST_ERROR;
2900      }
2901      else
2902      {
2903         if(array_key_exists("PREVIEW_PICTURE", $arFields))
2904         {
2905           $SAVED_PREVIEW_PICTURE = $arFields["PREVIEW_PICTURE"];
2906           if(is_array($arFields["PREVIEW_PICTURE"]))
2907             CFile::SaveForDB($arFields, "PREVIEW_PICTURE", "iblock");
2908           if($bWorkFlow)
2909             $COPY_PREVIEW_PICTURE = $arFields["PREVIEW_PICTURE"];
2910         }

не нашел в чем ошибка.
ответил 29 Май, 15 от hipiro (280 баллов)

Похожие вопросы

0 голосов
1 ответ
0 голосов
7 ответов
спросил 30 Июль, 13 от Aypuka (340 баллов)
0 голосов
3 ответов
0 голосов
2 ответов
0 голосов
5 ответов
спросил 05 Дек, 13 от Eoling (140 баллов)