-
Notifications
You must be signed in to change notification settings - Fork 11
/
pcd_delete_records_batch.py
114 lines (82 loc) · 2.91 KB
/
pcd_delete_records_batch.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import authenticate_with_msal
import json
import pandas as pd
import time
import uuid
from requests import Request
# Parameters
PathToEnvironmentJSON = "example-env.json"
EntityOfRecordsToDelete = "contacts"
PathToCSVOfRecords = "data\pcd_delete_records.csv"
BatchSize = 950
# Getting access token.
authentication = authenticate_with_msal.getAuthenticatedSession(PathToEnvironmentJSON)
session = authentication[0]
environmentURI = authentication[1]
# choose how you would like to act on errors
session.headers.update({"Prefer" : "odata.continue-on-error"})
# the post uri
batch_uri = f'{environmentURI}api/data/v9.2/$batch'
request_uri = f'/api/data/v9.2/{EntityOfRecordsToDelete}'
# read the CSV and convert to dataframe
df = pd.read_csv(PathToCSVOfRecords)
first = 0
last = BatchSize - 1
resultdf = df.copy()
resultdf['codes'] = ""
resultdf['messages'] = ""
resultdf['batch'] = ""
timeStart = time.perf_counter()
first = 0
last = BatchSize - 1
resultdf = df.copy()
resultdf['codes'] = ""
resultdf['messages'] = ""
resultdf['batch'] = ""
timeStart = time.perf_counter()
while first < len(df.index):
boundary = f"batch_{str(uuid.uuid4())}"
session.headers.update({"Content-Type" : f'multipart/mixed; boundary="{boundary}"'})
boundary = "--"+boundary
requestdf = df.loc[first:last]
body = ""
records = json.loads(requestdf.drop(columns='GUID').to_json(orient = "records"))
for index, row in requestdf.iterrows():
guid = row['GUID']
request = boundary + """
Content-Type: application/http
Content-Transfer-Encoding: binary
DELETE """ + request_uri + "(" + guid + ")" + """ HTTP/1.1
Content-Type: application/json
"""
body = body + request
body = (body + "\n" + boundary + "--").encode()
req = Request(
'POST',
batch_uri,
data = body,
headers = session.headers
).prepare()
r = session.send(req)
response = r.content.decode('utf-8')
delimiter = response[0:52]
responses = response.split(delimiter)
codes = []
messages = []
for i in range(1,len(responses)-1):
responses[i] = responses[i].removeprefix("\r\nContent-Type: application/http\r\nContent-Transfer-Encoding: binary\r\n\r\nHTTP/1.1 ")
responses[i] = responses[i].split('\r\n',1)
codes.append(responses[i][0])
messages.append(responses[i][1])
i += 1
resultdf.loc[first:last,'codes'] = codes
resultdf.loc[first:last,'messages'] = messages
resultdf.loc[first:last,'batch'] = boundary
resultdf.loc[first:last].to_csv(f"output\{boundary}.csv")
successes = sum(1 for i in codes if i == "204 No Content")
sent = len(requestdf.index)
print(f"Records {first} : {last} sent for import. {sent - successes} failures.")
first = last + 1
last = min(last + BatchSize,len(df.index))
print(f'IMPORTING TOOK: {round(time.perf_counter() - timeStart,0)} SECONDS ')
resultdf.to_csv("output\changes.csv")