|
14 | 14 | 'Person', |
15 | 15 | 'Post', |
16 | 16 | ] |
| 17 | +TRANSACTION_MAX_GROUPS = 5 |
17 | 18 |
|
18 | 19 |
|
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): |
20 | 43 | dataset_id = dataset.id() |
21 | 44 | connection = dataset.connection() |
22 | 45 |
|
| 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 |
23 | 52 | with dataset.transaction(): |
24 | | - query = dataset.query(kind=kind).limit( |
25 | | - FETCH_MAX).projection(['__key__']) |
26 | 53 | 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) |
32 | 54 |
|
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) |
34 | 59 | results.extend(curr_results) |
35 | 60 |
|
36 | | - more_results = len(curr_results) == FETCH_MAX |
| 61 | + if not results: |
| 62 | + return |
37 | 63 |
|
38 | 64 | # 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) |
41 | 76 |
|
42 | 77 |
|
43 | 78 | def remove_all_entities(): |
|
0 commit comments