Как заставить Salesforce REST API разбивать на страницы? - PullRequest
0 голосов
/ 04 марта 2020

Я использую оболочку simple_salesforce python для Salesforce REST API. У нас есть сотни тысяч записей, и я хотел бы разделить данные о продажах, чтобы не все записи обрабатывались одновременно.

Я пытался передать запрос вроде:

    results = salesforce_connection.query_all("SELECT my_field FROM my_model limit 2000 offset 50000")

, чтобы просмотреть записи с 50K по 52K, но получил ошибку, что смещение можно использовать только для первых 2000 записей. Как я могу использовать нумерацию страниц, чтобы мне не нужно было извлекать все записи сразу?

Ответы [ 2 ]

1 голос
/ 30 апреля 2020

Вы хотите использовать salesforce_connection.query (query = SOQL), а затем .query_more (nextRecordsUrl, True)

Поскольку .query () возвращает только 2000 записей, которые необходимо использовать .query_more, чтобы получить следующую страницу результатов

Из документов simple-salesforce

SOQL-запросы выполняются через:

sf.query("SELECT Id, Email FROM Contact WHERE LastName = 'Jones'")

Если из-за особенно большого результата Salesforce добавляет nextRecordsUrl к вашему запросу, например "nextRecordsUrl": "/services/data/v26.0/query/01gD0000002HU6KIAW-2000", вы можете получить дополнительные результаты либо с идентификатором, либо с полным URL (при использовании полного URL вы должны передать «True» в качестве второго аргумента)

sf.query_more("01gD0000002HU6KIAW-2000")
sf.query_more("/services/data/v26.0/query/01gD0000002HU6KIAW-2000", True)

Вот пример использования этого

 data = [] # list to hold all the records

 SOQL = "SELECT my_field FROM my_model"

 results = sf.query(query=SOQL) # api call

 ## loop through the results and add the records
 for rec in results['records']:
     rec.pop('attributes', None) # remove extra data
     data.append(rec) # add the record to the list


 ## check the 'done' attrubite in the response to see if there are more records
 ## While 'done' == False (more records to fetch) get the next page of records
 while(results['done'] == False):
     ## attribute 'nextRecordsUrl' holds the url to the next page of records
     results = sf.query_more(results['nextRecordsUrl', True])

     ## repeat the loop of adding the records
     for rec in results['records']:
         rec.pop('attributes', None)
         data.append(rec)

Циклический просмотр записей и использование данных

 ## loop through the records and get their attribute values
 for rec in data:
     # the attribute name will always be the same as the salesforce api name for that value
     print(rec['my_field'])

Как и в другом ответе, однако, это может начать использовать до много ресурсов. Но это то, что вы ищете, если хотите достичь нации страниц.

Возможно, создайте более сфокусированный оператор SOQL, чтобы получить только записи, необходимые для вашего варианта использования в этот конкретный c момент.

0 голосов
/ 05 марта 2020

LIMIT и OFFSET на самом деле не предназначены для такого использования, что если кто-то вставит или удалит запись на более ранней позиции (не говоря уже о том, что там нет ORDER BY). SF откроет правильный курсор для вас, используйте его.

https://pypi.org/project/simple-salesforce/ документы для "Запросы" говорят, что вы можете либо позвонить query, а затем query_more или вы можете go query_all. query_all будет l oop и продолжит вызывать query_more до тех пор, пока вы не исчерпаете курсор - но это может легко съесть вашу оперативную память.

В качестве альтернативы, вы можете посмотреть на массовые запросы, есть некоторые маги c в API, но я не знаю, подходит ли он для вашего случая использования. Это будут асинхронные вызовы, и они могут быть не реализованы в библиотеке. Это называется PK Chunking . Я не стал бы беспокоиться, если бы у вас не было миллионов записей.

...