Выполнение нескольких запросов за один http-вызов - Google Apps Script .fetch - PullRequest
1 голос
/ 29 февраля 2020

Я пытаюсь загрузить диапазон данных в Salesforce, используя следующий сценарий, однако в настоящее время он настроен на выполнение только одной строки за раз, что я использую для a для l oop в другой функции, однако, мои данные часто превышают 2000 строк, и время ожидания истекло. Я использую функцию для форматирования диапазона данных в формате JSON. Можно ли поместить sh каждый JSON в массив и передать его через мой HTTP-вызов за один go?

Загрузка в SF

function upsert(object, pl, id, idField, row) {
  var payload = tableJSON(pl);
  var sfService = getSfService();
  var userProps = PropertiesService.getUserProperties();
  var props = userProps.getProperties();
  var name = getSfService().serviceName_;
  var obj = JSON.parse(props['oauth2.' + name]);
  var instanceUrl = obj.instance_url;
  var queryUrl = instanceUrl + "/services/data/v42.0/sobjects/" + object +"/" + idField +"/" + id;
  var response = UrlFetchApp.fetch(queryUrl, {
    headers: {
      Authorization: "Bearer " + sfService.getAccessToken()
    },
    contentType: 'application/json',
    payload: payload,
    method: "PATCH",
    muteHttpExceptions: true
  });
}

таблица JSON

function tableJSON(arr) {
  var i, j, obj = {};
  for (i = 0; i < arr.length; i++) {
    for (j = 0; j < arr[0].length; j++) {
      obj[arr[0][j]] = arr[i][j];
    }
  }
  return JSON.stringify(obj);
}

Если кто-то знаком с этим, я в основном пытаюсь воссоздать то, что делает надстройка Data Connector by Google.

Опять же, я хочу взять диапазон данных, преобразовать это полезная нагрузка, которую я могу запустить через HTTP-вызов сразу и предпочтительно обновить каждую строку с успехом или кодом ответа / телом ошибки. У меня вопрос: как мне отформатировать полезную нагрузку, чтобы эта работа работала, как описано?

edit: я не включил все функции, такие как getSfService (). Если вы хотите увидеть все это, - это github , с которым я работал для создания своего кода.

edit: Это то, что в конечном итоге сработало для меня:

function upsertPage(object, idCol) {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getActiveSheet();
  var data = sheet.getDataRange().getDisplayValues();
  var sfService = getSfService();
  var userProps = PropertiesService.getUserProperties();
  var props = userProps.getProperties();
  var name = getSfService().serviceName_;
  var obj = JSON.parse(props['oauth2.' + name]);
  var instanceUrl = obj.instance_url;
  var idCol = colCt(idCol);
  var idField = data[0][idCol];
  var dataJSON = getJSON(data,idCol);
  var requestArr = [];
  for (i=1;i<data.length;i++){
    var id = data[i][idCol];
    var payload = JSON.stringify(dataJSON[i-1]);
    var request = {
      'url': instanceUrl + "/services/data/v42.0/sobjects/" + object +"/" + idField +"/" + id,
      'headers': {Authorization: "Bearer " + sfService.getAccessToken()},
      'contentType': 'application/json',
      'method': 'PATCH',
      'payload': payload,
      'muteHttpExceptions': true
      };    
    requestArr.push(request);
  };
var response = UrlFetchApp.fetchAll(requestArr);
  }
}

function colCt(colLetter){
  var abc = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'];
  for (i=0;i<abc.length;i++){
    var colLetter = colLetter.toUpperCase();
    if (colLetter === abc[i].toUpperCase()){
      return i;
      }
    }
  }

  function getJSON(data, extIdCol){
  var obj = {};
  var result = [];
  var headers = data[0];
  var cols = headers.length;
  var row = [];
  var extIdHeader = data[0][extIdCol];

  for (var i = 1, l = data.length; i < l; i++){
    // get a row to fill the object
    row = data[i];
    // clear object
    obj = {};
    for (var col = 0; col < cols; col++) 
    {
      // fill object with new values
      obj[headers[col]] = row[col];    
    }
    // add object in a final result
    result.push(obj);  
  }
  for(i=0;i<result.length;i++){
    delete result[i][extIdHeader];
    }
  return result;  
}

Ответы [ 2 ]

1 голос
/ 01 марта 2020

У меня нет опыта работы со сценариями Google Apps, но я могу помочь с битом SF. У вас есть список JSON объектов, которые, как мы надеемся, содержат действительный идентификатор записи SF, и вы хотите их массовое обновление?

Возможно, вам придется поэкспериментировать в Postman, SoapUI et c, немного с правым запрос. Или Workbench - неплохой вариант (экономит вам шаг входа в систему). В REST API Salesforce есть метод массового обновления нескольких объектов по идентификатору. Они даже не обязательно должны быть в одной таблице (представьте, что нужно обновить учетную запись, контакты, возможности в 1 запросе и при любой ошибке - откатить все 3, интересно!). Начните с https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_composite_sobjects_collections_update.htm

Если у вас нет идентификаторов записей SF, но ваш сценарий "d earforce, мне все равно, какой у вас уникальный идентификатор. система 12345, я даже не помню, отправлял ли я тебе эту запись раньше, go разбери свой беспорядок самостоятельно, вот новое состояние для сохранения, go выясни, нужно ли вставлять или обновлять"... Это называется операцией upsert, это выполнимо, если вы делаете некоторые приготовления (сначала создайте поле, помеченное как" External ID "). Но это не очень хорошо подходит для массовых выступлений, вам нужно быть немного креативным, как мой ответ здесь: https://salesforce.stackexchange.com/questions/274694/can-you-upsert-using-composite-sobject-tree

Из того, что я помню, у них есть ограничение максимум 200 «строк» ​​на запрос, и вы можете указать, если вы хотите "откат всей транзакции" или "сохранить то, что вы можете" режим. Оба эти примера являются синхронными (вы отправляете и ждете результатов). Если у вас все еще есть узкие места в производительности, вы можете захотеть заглянуть в асинхронный REST API, где вы отправляете задание, периодически вызываете «это уже сделано», а затем вы можете загрузить файл, сопоставить его с исходными строками ... сдвиг архитектуры кода, попробуйте сначала достичь предела 200, прежде чем начинать с преждевременной оптимизации.

0 голосов
/ 29 февраля 2020

Я думаю, что нашел свой собственный ответ, но все еще надеялся, что кто-то сможет подтвердить.

Если я использую UrlFetchApp.fetchAll и передал информацию для каждой строки как запрос, я думаю, что я мог бы сделать это в аль oop. Это верно?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...