Skip to content

Commit a477e31

Browse files
Merge pull request #262 from tigergraph/GML-1890-specify-atomicity-multiline-upserts
feat(atomic changes): set atomic level on batch upsert functions
2 parents a3f3365 + 8609c02 commit a477e31

File tree

6 files changed

+77
-17
lines changed

6 files changed

+77
-17
lines changed

pyTigerGraph/pyTigerGraphEdge.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -493,7 +493,7 @@ def upsertEdge(self, sourceVertexType: str, sourceVertexId: str, edgeType: str,
493493
return ret
494494

495495
def upsertEdges(self, sourceVertexType: str, edgeType: str, targetVertexType: str,
496-
edges: list, vertexMustExist=False) -> int:
496+
edges: list, vertexMustExist=False, atomic: bool = False) -> int:
497497
"""Upserts multiple edges (of the same type).
498498
499499
Args:
@@ -523,6 +523,11 @@ def upsertEdges(self, sourceVertexType: str, edgeType: str, targetVertexType: st
523523
```
524524
#operation-codes .
525525
For valid values of `<operator>` see https://docs.tigergraph.com/dev/restpp-api/built-in-endpoints
526+
atomic:
527+
The request is an atomic transaction. An atomic transaction means that updates to
528+
the database contained in the request are all-or-nothing: either all changes are
529+
successful, or none are successful. This uses the `gsql-atomic-level` header, and sets
530+
the value to `atomic` if `True`, and `nonatomic` if `False`. Default is `False`.
526531
527532
Returns:
528533
A single number of accepted (successfully upserted) edges (0 or positive integer).
@@ -552,7 +557,10 @@ def upsertEdges(self, sourceVertexType: str, edgeType: str, targetVertexType: st
552557
edgeType=edgeType,
553558
targetVertexType=targetVertexType,
554559
edges=edges)
555-
ret = self._req("POST", self.restppUrl + "/graph/" + self.graphname, data=data)[0][
560+
header = {}
561+
if atomic:
562+
header = {"gsql-atomic-level": "atomic"}
563+
ret = self._req("POST", self.restppUrl + "/graph/" + self.graphname, data=data, headers=header)[0][
556564
"accepted_edges"]
557565

558566
data = {sourceVertexType: {}}
@@ -601,7 +609,8 @@ def upsertEdges(self, sourceVertexType: str, edgeType: str, targetVertexType: st
601609

602610
def upsertEdgeDataFrame(self, df: 'pd.DataFrame', sourceVertexType: str, edgeType: str,
603611
targetVertexType: str, from_id: str = "", to_id: str = "",
604-
attributes: dict = None, vertexMustExist: bool = False) -> int:
612+
attributes: dict = None, vertexMustExist: bool = False,
613+
atomic: bool = False) -> int:
605614
"""Upserts edges from a Pandas DataFrame.
606615
607616
Args:
@@ -624,6 +633,11 @@ def upsertEdgeDataFrame(self, df: 'pd.DataFrame', sourceVertexType: str, edgeTyp
624633
the dataframe and target is the attribute name on the edge. When omitted,
625634
all columns would be upserted with their current names. In this case column names
626635
must match the edges's attribute names.
636+
atomic:
637+
The request is an atomic transaction. An atomic transaction means that updates to
638+
the database contained in the request are all-or-nothing: either all changes are
639+
successful, or none are successful. This uses the `gsql-atomic-level` header, and sets
640+
the value to `atomic` if `True`, and `nonatomic` if `False`. Default is `False`.
627641
628642
Returns:
629643
The number of edges upserted.
@@ -656,6 +670,7 @@ def upsertEdgeDataFrame(self, df: 'pd.DataFrame', sourceVertexType: str, edgeTyp
656670
targetVertexType,
657671
json_up,
658672
vertexMustExist=vertexMustExist,
673+
atomic=atomic
659674
)
660675

661676
if logger.level == logging.DEBUG:

pyTigerGraph/pyTigerGraphSchema.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,8 @@ def upsertData(self, data: Union[str, object], atomic: bool = False, ackAll: boo
9595
atomic:
9696
The request is an atomic transaction. An atomic transaction means that updates to
9797
the database contained in the request are all-or-nothing: either all changes are
98-
successful, or none are successful.
98+
successful, or none are successful. This uses the `gsql-atomic-level` header, and sets
99+
the value to `atomic` if `True`, and `nonatomic` if `False`. Default is `False`.
99100
ackAll:
100101
If `True`, the request will return after all GPE instances have acknowledged the
101102
POST. Otherwise, the request will return immediately after RESTPP processes the POST.

pyTigerGraph/pyTigerGraphVertex.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ def upsertVertex(self, vertexType: str, vertexId: str, attributes: dict = None)
242242

243243
return ret
244244

245-
def upsertVertices(self, vertexType: str, vertices: list) -> int:
245+
def upsertVertices(self, vertexType: str, vertices: list, atomic: bool = False) -> int:
246246
"""Upserts multiple vertices (of the same type).
247247
248248
See the description of ``upsertVertex`` for generic information.
@@ -273,6 +273,11 @@ def upsertVertices(self, vertexType: str, vertices: list) -> int:
273273
----
274274
275275
For valid values of `<operator>` see xref:tigergraph-server:API:built-in-endpoints.adoc#_operation_codes[Operation codes].
276+
atomic:
277+
The request is an atomic transaction. An atomic transaction means that updates to
278+
the database contained in the request are all-or-nothing: either all changes are
279+
successful, or none are successful. This uses the `gsql-atomic-level` header, and sets
280+
the value to `atomic` if `True`, and `nonatomic` if `False`. Default is `False`.
276281
277282
Returns:
278283
A single number of accepted (successfully upserted) vertices (0 or positive integer).
@@ -284,6 +289,10 @@ def upsertVertices(self, vertexType: str, vertices: list) -> int:
284289
logger.info("entry: upsertVertices")
285290
if logger.level == logging.DEBUG:
286291
logger.debug("params: " + self._locals(locals()))
292+
293+
headers = {}
294+
if atomic:
295+
headers["gsql-atomic-level"] = "atomic"
287296

288297
data = {}
289298
for v in vertices:
@@ -292,7 +301,7 @@ def upsertVertices(self, vertexType: str, vertices: list) -> int:
292301
data = json.dumps({"vertices": {vertexType: data}})
293302

294303
ret = self._req("POST", self.restppUrl + "/graph/" +
295-
self.graphname, data=data)[0]["accepted_vertices"]
304+
self.graphname, data=data, headers=headers)[0]["accepted_vertices"]
296305

297306
if logger.level == logging.DEBUG:
298307
logger.debug("return: " + str(ret))
@@ -301,7 +310,7 @@ def upsertVertices(self, vertexType: str, vertices: list) -> int:
301310
return ret
302311

303312
def upsertVertexDataFrame(self, df: 'pd.DataFrame', vertexType: str, v_id: bool = None,
304-
attributes: dict = None) -> int:
313+
attributes: dict = None, atomic: bool = False) -> int:
305314
"""Upserts vertices from a Pandas DataFrame.
306315
307316
Args:
@@ -317,6 +326,11 @@ def upsertVertexDataFrame(self, df: 'pd.DataFrame', vertexType: str, v_id: bool
317326
the dataframe and target is the attribute name in the graph vertex. When omitted,
318327
all columns would be upserted with their current names. In this case column names
319328
must match the vertex's attribute names.
329+
atomic:
330+
The request is an atomic transaction. An atomic transaction means that updates to
331+
the database contained in the request are all-or-nothing: either all changes are
332+
successful, or none are successful. This uses the `gsql-atomic-level` header, and sets
333+
the value to `atomic` if `True`, and `nonatomic` if `False`. Default is `False`.
320334
321335
Returns:
322336
The number of vertices upserted.
@@ -327,7 +341,7 @@ def upsertVertexDataFrame(self, df: 'pd.DataFrame', vertexType: str, v_id: bool
327341

328342
json_up = _prep_upsert_vertex_dataframe(
329343
df=df, v_id=v_id, attributes=attributes)
330-
ret = self.upsertVertices(vertexType=vertexType, vertices=json_up)
344+
ret = self.upsertVertices(vertexType=vertexType, vertices=json_up, atomic=atomic)
331345

332346
if logger.level == logging.DEBUG:
333347
logger.debug("return: " + str(ret))

pyTigerGraph/pytgasync/pyTigerGraphEdge.py

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,7 @@ async def upsertEdge(self, sourceVertexType: str, sourceVertexId: str, edgeType:
435435
```
436436
{"visits": (1482, "+"), "max_duration": (371, "max")}
437437
```
438-
For valid values of `<operator>` see https://docs.tigergraph.com/dev/restpp-api/built-in-endpoints#operation-codes .
438+
For valid values of `<operator>` see https://docs.tigergraph.com/dev/restpp-api/built-in-endpoints#operation-codes.
439439
440440
Returns:
441441
A single number of accepted (successfully upserted) edges (0 or 1).
@@ -467,7 +467,7 @@ async def upsertEdge(self, sourceVertexType: str, sourceVertexId: str, edgeType:
467467
return ret
468468

469469
async def upsertEdges(self, sourceVertexType: str, edgeType: str, targetVertexType: str,
470-
edges: list) -> int:
470+
edges: list, atomic: bool = False) -> int:
471471
"""Upserts multiple edges (of the same type).
472472
473473
Args:
@@ -494,6 +494,11 @@ async def upsertEdges(self, sourceVertexType: str, edgeType: str, targetVertexTy
494494
]
495495
```
496496
For valid values of `<operator>` see https://docs.tigergraph.com/dev/restpp-api/built-in-endpoints#operation-codes .
497+
atomic:
498+
The request is an atomic transaction. An atomic transaction means that updates to
499+
the database contained in the request are all-or-nothing: either all changes are
500+
successful, or none are successful. This uses the `gsql-atomic-level` header, and sets
501+
the value to `atomic` if `True`, and `nonatomic` if `False`. Default is `False`.
497502
498503
Returns:
499504
A single number of accepted (successfully upserted) edges (0 or positive integer).
@@ -524,6 +529,11 @@ async def upsertEdges(self, sourceVertexType: str, edgeType: str, targetVertexTy
524529
edgeType=edgeType,
525530
targetVertexType=targetVertexType,
526531
edges=edges)
532+
533+
headers = {}
534+
if atomic:
535+
headers["gsql-atomic-level"] = "atomic"
536+
527537
ret = await self._req("POST", self.restppUrl + "/graph/" + self.graphname, data=data)
528538
ret = ret[0]["accepted_edges"]
529539

@@ -535,7 +545,7 @@ async def upsertEdges(self, sourceVertexType: str, edgeType: str, targetVertexTy
535545

536546
async def upsertEdgeDataFrame(self, df: 'pd.DataFrame', sourceVertexType: str, edgeType: str,
537547
targetVertexType: str, from_id: str = "", to_id: str = "",
538-
attributes: dict = None) -> int:
548+
attributes: dict = None, atomic: bool = False) -> int:
539549
"""Upserts edges from a Pandas DataFrame.
540550
541551
Args:
@@ -558,6 +568,11 @@ async def upsertEdgeDataFrame(self, df: 'pd.DataFrame', sourceVertexType: str, e
558568
the dataframe and target is the attribute name on the edge. When omitted,
559569
all columns would be upserted with their current names. In this case column names
560570
must match the edges's attribute names.
571+
atomic:
572+
The request is an atomic transaction. An atomic transaction means that updates to
573+
the database contained in the request are all-or-nothing: either all changes are
574+
successful, or none are successful. This uses the `gsql-atomic-level` header, and sets
575+
the value to `atomic` if `True`, and `nonatomic` if `False`. Default is `False`.
561576
562577
Returns:
563578
The number of edges upserted.
@@ -567,7 +582,7 @@ async def upsertEdgeDataFrame(self, df: 'pd.DataFrame', sourceVertexType: str, e
567582
logger.debug("params: " + self._locals(locals()))
568583

569584
json_up = _prep_upsert_edge_dataframe(df, from_id, to_id, attributes)
570-
ret = await self.upsertEdges(sourceVertexType, edgeType, targetVertexType, json_up)
585+
ret = await self.upsertEdges(sourceVertexType, edgeType, targetVertexType, json_up, atomic=atomic)
571586

572587
if logger.level == logging.DEBUG:
573588
logger.debug("return: " + str(ret))

pyTigerGraph/pytgasync/pyTigerGraphSchema.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,8 @@ async def upsertData(self, data: Union[str, object], atomic: bool = False, ackAl
9595
atomic:
9696
The request is an atomic transaction. An atomic transaction means that updates to
9797
the database contained in the request are all-or-nothing: either all changes are
98-
successful, or none are successful.
98+
successful, or none are successful. This uses the `gsql-atomic-level` header, and sets
99+
the value to `atomic` if `True`, and `nonatomic` if `False`.
99100
ackAll:
100101
If `True`, the request will return after all GPE instances have acknowledged the
101102
POST. Otherwise, the request will return immediately after RESTPP processes the POST.

pyTigerGraph/pytgasync/pyTigerGraphVertex.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ async def upsertVertex(self, vertexType: str, vertexId: str, attributes: dict =
249249

250250
return ret
251251

252-
async def upsertVertices(self, vertexType: str, vertices: list) -> int:
252+
async def upsertVertices(self, vertexType: str, vertices: list, atomic: bool = False) -> int:
253253
"""Upserts multiple vertices (of the same type).
254254
255255
See the description of ``upsertVertex`` for generic information.
@@ -280,6 +280,11 @@ async def upsertVertices(self, vertexType: str, vertices: list) -> int:
280280
----
281281
282282
For valid values of `<operator>` see xref:tigergraph-server:API:built-in-endpoints.adoc#_operation_codes[Operation codes].
283+
atomic:
284+
The request is an atomic transaction. An atomic transaction means that updates to
285+
the database contained in the request are all-or-nothing: either all changes are
286+
successful, or none are successful. This uses the `gsql-atomic-level` header, and sets
287+
the value to `atomic` if `True`, and `nonatomic` if `False`. Defaults to False.
283288
284289
Returns:
285290
A single number of accepted (successfully upserted) vertices (0 or positive integer).
@@ -292,13 +297,17 @@ async def upsertVertices(self, vertexType: str, vertices: list) -> int:
292297
if logger.level == logging.DEBUG:
293298
logger.debug("params: " + self._locals(locals()))
294299

300+
headers = {}
301+
if atomic:
302+
headers["gsql-atomic-level"] = "atomic"
303+
295304
data = {}
296305
for v in vertices:
297306
vals = _upsert_attrs(v[1])
298307
data[v[0]] = vals
299308
data = json.dumps({"vertices": {vertexType: data}})
300309

301-
ret = await self._req("POST", self.restppUrl + "/graph/" + self.graphname, data=data)
310+
ret = await self._req("POST", self.restppUrl + "/graph/" + self.graphname, data=data, headers=headers)
302311
ret = ret[0]["accepted_vertices"]
303312

304313
if logger.level == logging.DEBUG:
@@ -308,7 +317,7 @@ async def upsertVertices(self, vertexType: str, vertices: list) -> int:
308317
return ret
309318

310319
async def upsertVertexDataFrame(self, df: 'pd.DataFrame', vertexType: str, v_id: bool = None,
311-
attributes: dict = None) -> int:
320+
attributes: dict = None, atomic: bool = False) -> int:
312321
"""Upserts vertices from a Pandas DataFrame.
313322
314323
Args:
@@ -324,6 +333,11 @@ async def upsertVertexDataFrame(self, df: 'pd.DataFrame', vertexType: str, v_id:
324333
the dataframe and target is the attribute name in the graph vertex. When omitted,
325334
all columns would be upserted with their current names. In this case column names
326335
must match the vertex's attribute names.
336+
atomic:
337+
The request is an atomic transaction. An atomic transaction means that updates to
338+
the database contained in the request are all-or-nothing: either all changes are
339+
successful, or none are successful. This uses the `gsql-atomic-level` header, and sets
340+
the value to `atomic` if `True`, and `nonatomic` if `False`. Defaults to False.
327341
328342
Returns:
329343
The number of vertices upserted.
@@ -334,7 +348,7 @@ async def upsertVertexDataFrame(self, df: 'pd.DataFrame', vertexType: str, v_id:
334348

335349
json_up = _prep_upsert_vertex_dataframe(
336350
df=df, v_id=v_id, attributes=attributes)
337-
ret = await self.upsertVertices(vertexType=vertexType, vertices=json_up)
351+
ret = await self.upsertVertices(vertexType=vertexType, vertices=json_up, atomic=atomic)
338352

339353
if logger.level == logging.DEBUG:
340354
logger.debug("return: " + str(ret))

0 commit comments

Comments
 (0)