|
18 | 18 | { |
19 | 19 | "parameters": { |
20 | 20 | "operation": "executeQuery", |
21 | | - "query": "SELECT table_name FROM information_schema.tables WHERE table_schema = 'public' AND table_type = 'BASE TABLE' ORDER BY table_name", |
| 21 | + "query": "SELECT t.table_name, COALESCE(s.n_tup_ins + s.n_tup_upd + s.n_tup_del, 0)::text as mod_count FROM information_schema.tables t LEFT JOIN pg_stat_user_tables s ON s.relname = t.table_name WHERE t.table_schema = 'public' AND t.table_type = 'BASE TABLE' ORDER BY t.table_name", |
22 | 22 | "options": {} |
23 | 23 | }, |
24 | 24 | "id": "pg-list-tables", |
25 | | - "name": "List PG Tables", |
| 25 | + "name": "List Tables + Mod Counts", |
26 | 26 | "type": "n8n-nodes-base.postgres", |
27 | 27 | "typeVersion": 2.6, |
28 | 28 | "position": [220, 0] |
29 | 29 | }, |
30 | | - { |
31 | | - "parameters": {"options": {}}, |
32 | | - "id": "split-batches", |
33 | | - "name": "Loop Over Tables", |
34 | | - "type": "n8n-nodes-base.splitInBatches", |
35 | | - "typeVersion": 3, |
36 | | - "position": [440, 0] |
37 | | - }, |
38 | | - { |
39 | | - "parameters": { |
40 | | - "operation": "create", |
41 | | - "documentId": {"__rl": true, "mode": "id", "value": "={{ $env.GOOGLE_SHEETS_ID }}"}, |
42 | | - "title": "={{ $json.table_name }}" |
43 | | - }, |
44 | | - "id": "sheets-create", |
45 | | - "name": "Ensure Sheet Exists", |
46 | | - "type": "n8n-nodes-base.googleSheets", |
47 | | - "typeVersion": 4.7, |
48 | | - "position": [660, 0], |
49 | | - "onError": "continueRegularOutput" |
50 | | - }, |
51 | 30 | { |
52 | 31 | "parameters": { |
53 | | - "operation": "executeQuery", |
54 | | - "query": "=SELECT * FROM {{ $('Loop Over Tables').item.json.table_name }}", |
55 | | - "options": {} |
| 32 | + "jsCode": "const staticData = $getWorkflowStaticData('global');\nif (!staticData.mods) staticData.mods = {};\n\nconst changed = [];\nfor (const item of $input.all()) {\n const name = item.json.table_name;\n const mods = item.json.mod_count;\n if (staticData.mods[name] !== mods) {\n staticData.mods[name] = mods;\n changed.push({ json: { table_name: name } });\n }\n}\n\nif (changed.length === 0) {\n return [{ json: { table_name: '__none__', skipped: true } }];\n}\nreturn changed;" |
56 | 33 | }, |
57 | | - "id": "pg-dump-table", |
58 | | - "name": "Dump Table", |
59 | | - "type": "n8n-nodes-base.postgres", |
60 | | - "typeVersion": 2.6, |
61 | | - "position": [880, 0] |
| 34 | + "id": "filter-changed", |
| 35 | + "name": "Filter Changed Tables", |
| 36 | + "type": "n8n-nodes-base.code", |
| 37 | + "typeVersion": 2, |
| 38 | + "position": [440, 0] |
62 | 39 | }, |
63 | 40 | { |
64 | 41 | "parameters": { |
65 | 42 | "conditions": { |
66 | 43 | "options": {"caseSensitive": true, "leftValue": "", "typeValidation": "strict"}, |
67 | 44 | "conditions": [ |
68 | 45 | { |
69 | | - "id": "has-rows", |
70 | | - "leftValue": "={{ $input.all().length }}", |
71 | | - "rightValue": 0, |
72 | | - "operator": {"type": "number", "operation": "gt"} |
| 46 | + "id": "not-skipped", |
| 47 | + "leftValue": "={{ $json.skipped }}", |
| 48 | + "rightValue": true, |
| 49 | + "operator": {"type": "boolean", "operation": "notEquals"} |
73 | 50 | } |
74 | 51 | ], |
75 | 52 | "combinator": "and" |
76 | 53 | }, |
77 | 54 | "options": {} |
78 | 55 | }, |
79 | | - "id": "if-has-data", |
80 | | - "name": "Has Data?", |
| 56 | + "id": "if-has-changes", |
| 57 | + "name": "Any Changes?", |
81 | 58 | "type": "n8n-nodes-base.if", |
82 | 59 | "typeVersion": 2.3, |
83 | | - "position": [1100, 0] |
| 60 | + "position": [660, 0] |
| 61 | + }, |
| 62 | + { |
| 63 | + "parameters": {"options": {}}, |
| 64 | + "id": "split-batches", |
| 65 | + "name": "Loop Over Tables", |
| 66 | + "type": "n8n-nodes-base.splitInBatches", |
| 67 | + "typeVersion": 3, |
| 68 | + "position": [880, -100] |
| 69 | + }, |
| 70 | + { |
| 71 | + "parameters": { |
| 72 | + "operation": "create", |
| 73 | + "documentId": {"__rl": true, "mode": "id", "value": "={{ $env.GOOGLE_SHEETS_ID }}"}, |
| 74 | + "title": "={{ $json.table_name }}" |
| 75 | + }, |
| 76 | + "id": "sheets-create", |
| 77 | + "name": "Ensure Sheet Exists", |
| 78 | + "type": "n8n-nodes-base.googleSheets", |
| 79 | + "typeVersion": 4.7, |
| 80 | + "position": [1100, -100], |
| 81 | + "onError": "continueRegularOutput" |
84 | 82 | }, |
85 | 83 | { |
86 | 84 | "parameters": { |
|
94 | 92 | "typeVersion": 4.7, |
95 | 93 | "position": [1320, -100] |
96 | 94 | }, |
| 95 | + { |
| 96 | + "parameters": { |
| 97 | + "operation": "executeQuery", |
| 98 | + "query": "=SELECT * FROM {{ $('Loop Over Tables').item.json.table_name }}", |
| 99 | + "options": {} |
| 100 | + }, |
| 101 | + "id": "pg-dump-table", |
| 102 | + "name": "Dump Table", |
| 103 | + "type": "n8n-nodes-base.postgres", |
| 104 | + "typeVersion": 2.6, |
| 105 | + "position": [1540, -100] |
| 106 | + }, |
97 | 107 | { |
98 | 108 | "parameters": { |
99 | 109 | "operation": "append", |
|
109 | 119 | "name": "Write to Sheet", |
110 | 120 | "type": "n8n-nodes-base.googleSheets", |
111 | 121 | "typeVersion": 4.7, |
112 | | - "position": [1540, -100] |
| 122 | + "position": [1760, -100] |
113 | 123 | } |
114 | 124 | ], |
115 | 125 | "connections": { |
116 | | - "Every 5 Minutes": {"main": [[{"node": "List PG Tables", "type": "main", "index": 0}]]}, |
117 | | - "List PG Tables": {"main": [[{"node": "Loop Over Tables", "type": "main", "index": 0}]]}, |
| 126 | + "Every 5 Minutes": {"main": [[{"node": "List Tables + Mod Counts", "type": "main", "index": 0}]]}, |
| 127 | + "List Tables + Mod Counts": {"main": [[{"node": "Filter Changed Tables", "type": "main", "index": 0}]]}, |
| 128 | + "Filter Changed Tables": {"main": [[{"node": "Any Changes?", "type": "main", "index": 0}]]}, |
| 129 | + "Any Changes?": {"main": [[{"node": "Loop Over Tables", "type": "main", "index": 0}], []]}, |
118 | 130 | "Loop Over Tables": {"main": [[], [{"node": "Ensure Sheet Exists", "type": "main", "index": 0}]]}, |
119 | | - "Ensure Sheet Exists": {"main": [[{"node": "Dump Table", "type": "main", "index": 0}]]}, |
120 | | - "Dump Table": {"main": [[{"node": "Has Data?", "type": "main", "index": 0}]]}, |
121 | | - "Has Data?": {"main": [[{"node": "Clear Sheet", "type": "main", "index": 0}], [{"node": "Loop Over Tables", "type": "main", "index": 0}]]}, |
122 | | - "Clear Sheet": {"main": [[{"node": "Write to Sheet", "type": "main", "index": 0}]]}, |
| 131 | + "Ensure Sheet Exists": {"main": [[{"node": "Clear Sheet", "type": "main", "index": 0}]]}, |
| 132 | + "Clear Sheet": {"main": [[{"node": "Dump Table", "type": "main", "index": 0}]]}, |
| 133 | + "Dump Table": {"main": [[{"node": "Write to Sheet", "type": "main", "index": 0}]]}, |
123 | 134 | "Write to Sheet": {"main": [[{"node": "Loop Over Tables", "type": "main", "index": 0}]]} |
124 | 135 | }, |
125 | 136 | "settings": {"executionOrder": "v1"} |
|
0 commit comments