Skip to content

Commit 5ad0798

Browse files
committed
Refactoring remove_kind to make while loop clearer.
Also stumbled upon other datastore gotchas (non-ancestor deletes in a transaction) and added printing to indicate what is being deleted.
1 parent 25179c9 commit 5ad0798

File tree

1 file changed

+47
-12
lines changed

1 file changed

+47
-12
lines changed

regression/clear_datastore.py

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,30 +14,65 @@
1414
'Person',
1515
'Post',
1616
]
17+
TRANSACTION_MAX_GROUPS = 5
1718

1819

19-
def remove_kind(dataset, kind):
20+
def fetch_keys(dataset, kind, fetch_max=FETCH_MAX, query=None):
21+
if query is None:
22+
query = dataset.query(kind=kind).limit(
23+
fetch_max).projection(['__key__'])
24+
# Make new query with start cursor if a previously set cursor
25+
# exists.
26+
if query._cursor is not None:
27+
query = query.with_cursor(query.cursor())
28+
29+
return query, query.fetch()
30+
31+
32+
def get_ancestors(entities):
33+
# NOTE: A key will always have at least one path element.
34+
key_roots = [entity.key().path()[0] for entity in entities]
35+
# Turn into hashable type so we can use set to get unique roots.
36+
# Also sorted the items() to ensure uniqueness.
37+
key_roots = [tuple(sorted(root.items())) for root in key_roots]
38+
# Cast back to dictionary.
39+
return [dict(root) for root in set(key_roots)]
40+
41+
42+
def delete_entities(dataset, entities):
2043
dataset_id = dataset.id()
2144
connection = dataset.connection()
2245

46+
key_pbs = [entity.key().to_protobuf() for entity in entities]
47+
connection.delete_entities(dataset_id, key_pbs)
48+
49+
50+
def remove_kind(dataset, kind):
51+
delete_outside_transaction = False
2352
with dataset.transaction():
24-
query = dataset.query(kind=kind).limit(
25-
FETCH_MAX).projection(['__key__'])
2653
results = []
27-
more_results = True
28-
while more_results:
29-
# Make new query.
30-
if query._cursor is not None:
31-
query = query.with_cursor(query._cursor)
3254

33-
curr_results = query.fetch()
55+
query, curr_results = fetch_keys(dataset, kind)
56+
results.extend(curr_results)
57+
while curr_results:
58+
query, curr_results = fetch_keys(dataset, kind, query=query)
3459
results.extend(curr_results)
3560

36-
more_results = len(curr_results) == FETCH_MAX
61+
if not results:
62+
return
3763

3864
# Now that we have all results, we seek to delete.
39-
key_pbs = [entity.key().to_protobuf() for entity in results]
40-
connection.delete_entities(dataset_id, key_pbs)
65+
print 'Deleting keys:'
66+
print results
67+
68+
ancestors = get_ancestors(results)
69+
if len(ancestors) > TRANSACTION_MAX_GROUPS:
70+
delete_outside_transaction = True
71+
else:
72+
delete_entities(dataset, results)
73+
74+
if delete_outside_transaction:
75+
delete_entities(dataset, results)
4176

4277

4378
def remove_all_entities():

0 commit comments

Comments
 (0)