версия 47.0
Bulk API 2.0 NOT SOQL
Создание сценария python с использованием модулей request и arguments_oathlib для test.salesforce .com / services / oauth2 / token для генерации токенов доступа и функции, которая объединяет фрагменты результатов до тех пор, пока не будет обнаружен последний фрагмент, а затем создает строку json из результатов.
мы знаем у нас в контакте 1479552 строки.
Проблема:
SELECT id,Name,Email,Phone FROM Contact LIMIT 1850000
производит
ccntr: 0
size of this chunk: 113666341 bytes
size of total chunk: 113666341 bytes
Sforce-NumberOfRecords for this chunk: 1479553
Sforce-Locator for this chunk: null
=======================
length of bigStr : 113643182 chars
возвращает все 1479552 строки (плюс одна строка заголовка), но
SELECT id,Name,Email,Phone FROM Contact
производит
ccntr: 0
size of this chunk: 18952552 bytes
size of total chunk: 18952552 bytes
Sforce-NumberOfRecords for this chunk: 246370
Sforce-Locator for this chunk: 246370
-----------------------
ccntr: 1
size of this chunk: 18943704 bytes
size of total chunk: 37896256 bytes
Sforce-NumberOfRecords for this chunk: 245824
Sforce-Locator for this chunk: 492194
-----------------------
ccntr: 2
size of this chunk: 118 bytes
size of total chunk: 37896374 bytes
Sforce-NumberOfRecords not found
Sforce-Locator not found
=======================
length of bigStr : 37892718 chars
total rows for decoded_content_list: 49219
возвращает только 492196 !!! Что случилось с этим ?? !! ??
И я заметил, что при использовании предложения LIMIT возвращаются только два блока, первый содержит все или почти все данные, а второй только 110 байтов или около того, в то время как без LIMIT возвращаются 3 чанка примерно одинакового размера.
Есть и еще - с предложением LIMIT на месте один чанк возвращается с заголовком «Sforce-Locator» со значением «null» допустимая строка. Обратите внимание, что в последнем фрагменте результата без предложения LIMIT отсутствует заголовок Sforce-Locater на всех . Таким образом, поведение отличается по крайней мере на двух фронтах.
Может ли кто-нибудь проверить и / или объяснить это поведение? А еще лучше, скажите мне, как обойти это?
Дополнительный вопрос: SOQL возвращает столбцы в том же порядке, как указано в операторе SELECT, как и ожидалось. Но когда тот же оператор выполняется с помощью Bulk API 2.0, результаты возвращаются со столбцами, отсортированными в алфавитном порядке, например, Email, id, Name, Phone. Это не артефакт того, что python не поддерживает порядок в словах, я проверил необработанные данные CSV, возвращаемые запросом, прежде чем он преобразуется в JSON.
Некоторые фрагменты кода
def getBulkQueryResults( url_to_use, access_token, operation_id, isDebug=False):
finished = False
bio = io.BytesIO()
url_full = "{0}/jobs/query/{1}/results".format( url_to_use, operation_id)
while not finished:
r = requests.get(url_full, headers=headers ) # an object of type Response
header_dict = r.headers
bio.write( r.content)
if( 'Sforce-Locator' not in header_dict): # this may be the problem
finished = True
else:
url_full = url_full + '/?locator=' + header_dict['Sforce-Locator']
totbio = bio.getvalue()
bigStr = totbio.decode('utf-8')
decoded_content_list = bigStr.split('\n')
print( "=======================")
print( "length of bigStr : {0} chars".format( str( len(bigStr))))
print( "total rows for decoded_content_list: {0}".format ( str( len( decoded_content_list))))
json_str = convertCsvListToJsonStr( decoded_content_list, isDebug)
return json_str
def executeBulkQuery( url_to_use, access_token, query_to_use, isDebug=False):
if isDebug: print( "executeBulkQuery - entered")
# to to retrieve some data
headers = { 'Authorization' : "Bearer {0}".format( access_token)
, 'Content-Type' : "application/json; charset=utf-8"
, 'Accept' : "application/json"
}
boddy_dict = { 'operation' : "query" , 'query' : query_to_use }
boddy_json = json.dumps( boddy_dict)
url_full = "{0}/jobs/query".format( url_to_use)
r = requests.post( url_full, headers=headers, data=boddy_json )
r_dict = r.json()
query_id = r_dict['id']
finished = False
while not finished:
if( checkBulkQueryStatus( url_to_use, access_token, query_id) == "JobComplete"):
finished = True
json_str = getBulkQueryResults( url_to_use, access_token, query_id, isDebug)
return json_str
TIA,
code_warrior