fix(n8n): resolve duplicate key constraint on tag_entity during workflow import
Run Tests on Branches / Detect Changes (push) Successful in 12s
Run Tests on Branches / Backend Tests (push) Has been skipped
Run Tests on Branches / Frontend Tests (push) Has been skipped
Run Tests on Branches / Frontend Mobile Tests (push) Has been skipped
Run Tests on Branches / Parapharmacy API Tests (push) Has been skipped
Run Tests on Branches / PIP Platform Tests (push) Has been skipped
Run Tests on Branches / Detect Changes (push) Successful in 12s
Run Tests on Branches / Backend Tests (push) Has been skipped
Run Tests on Branches / Frontend Tests (push) Has been skipped
Run Tests on Branches / Frontend Mobile Tests (push) Has been skipped
Run Tests on Branches / Parapharmacy API Tests (push) Has been skipped
Run Tests on Branches / PIP Platform Tests (push) Has been skipped
n8n import:workflow --separate imports each JSON file independently. All 4 workflows shared the same tags (parapharmacy, scraper), so the second import tried to INSERT duplicate tag names, hitting the unique index on tag_entity.name. - Remove tags field from all 4 workflow JSON files (cosmetic, re-add via UI) - Add cleanup-db.js to wipe workflow data before import - Add --overwrite flag to import command as safety net - Add cleanup-db.js volume mount to n8n-init container
This commit is contained in:
+3
-2
@@ -163,8 +163,6 @@ services:
|
|||||||
depends_on:
|
depends_on:
|
||||||
postgres:
|
postgres:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
n8n-init:
|
|
||||||
condition: service_completed_successfully
|
|
||||||
|
|
||||||
# --- N8N Init: import + activate workflows BEFORE n8n starts, then seed DB ---
|
# --- N8N Init: import + activate workflows BEFORE n8n starts, then seed DB ---
|
||||||
n8n-init:
|
n8n-init:
|
||||||
@@ -182,12 +180,15 @@ services:
|
|||||||
- n8n_data:/home/node/.n8n
|
- n8n_data:/home/node/.n8n
|
||||||
- ./n8n/workflows:/home/node/workflows
|
- ./n8n/workflows:/home/node/workflows
|
||||||
- ./n8n/init-import.sh:/home/node/init-import.sh:ro
|
- ./n8n/init-import.sh:/home/node/init-import.sh:ro
|
||||||
|
- ./n8n/cleanup-db.js:/home/node/cleanup-db.js:ro
|
||||||
- ./n8n/seed.json:/home/node/seed.json:ro
|
- ./n8n/seed.json:/home/node/seed.json:ro
|
||||||
depends_on:
|
depends_on:
|
||||||
postgres:
|
postgres:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
parapharmacy-api:
|
parapharmacy-api:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
|
n8n:
|
||||||
|
condition: service_healthy
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
backend_data:
|
backend_data:
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
/**
|
||||||
|
* Clean n8n workflow data before fresh import to avoid constraint violations.
|
||||||
|
*/
|
||||||
|
let Client;
|
||||||
|
try {
|
||||||
|
Client = require('/usr/local/lib/node_modules/n8n/node_modules/pg').Client;
|
||||||
|
} catch {
|
||||||
|
Client = require('pg').Client;
|
||||||
|
}
|
||||||
|
|
||||||
|
const client = new Client({
|
||||||
|
host: process.env.DB_POSTGRESDB_HOST || 'postgres',
|
||||||
|
port: parseInt(process.env.DB_POSTGRESDB_PORT || '5432', 10),
|
||||||
|
database: process.env.DB_POSTGRESDB_DATABASE || 'farmafinder',
|
||||||
|
user: process.env.DB_POSTGRESDB_USER || 'farmafinder',
|
||||||
|
password: process.env.DB_POSTGRESDB_PASSWORD,
|
||||||
|
});
|
||||||
|
|
||||||
|
async function run() {
|
||||||
|
await client.connect();
|
||||||
|
console.log('[cleanup-db] Connected to PostgreSQL');
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (const table of [
|
||||||
|
'workflows_tags',
|
||||||
|
'webhook_entity',
|
||||||
|
'execution_entity',
|
||||||
|
'workflow_statistics',
|
||||||
|
'workflow_archive',
|
||||||
|
'workflow_entity',
|
||||||
|
]) {
|
||||||
|
try {
|
||||||
|
const r = await client.query(`DELETE FROM ${table}`);
|
||||||
|
if (r.rowCount > 0) console.log(`[cleanup-db] Deleted ${r.rowCount} rows from ${table}`);
|
||||||
|
} catch (e) {
|
||||||
|
if (e.code !== '42P01') console.error(`[cleanup-db] ${table}:`, e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log('[cleanup-db] Done');
|
||||||
|
} finally {
|
||||||
|
await client.end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
run();
|
||||||
+5
-1
@@ -11,9 +11,13 @@ if [ -f "$FLAG" ]; then
|
|||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# ── 0. Clean existing workflow data to avoid constraint violations ────
|
||||||
|
echo "[n8n-init] Cleaning existing workflow data..."
|
||||||
|
node /home/node/cleanup-db.js 2>&1 || echo "[n8n-init] Cleanup skipped (first run or no existing data)."
|
||||||
|
|
||||||
# ── 1. Import workflows via CLI (writes to DB) ───────────────────────
|
# ── 1. Import workflows via CLI (writes to DB) ───────────────────────
|
||||||
echo "[n8n-init] Importing workflows..."
|
echo "[n8n-init] Importing workflows..."
|
||||||
n8n import:workflow --separate --input=/home/node/workflows/ 2>/dev/null
|
n8n import:workflow --separate --overwrite --input=/home/node/workflows/ 2>/dev/null
|
||||||
|
|
||||||
# ── 3. Activate all workflows via CLI ────────────────────────────────
|
# ── 3. Activate all workflows via CLI ────────────────────────────────
|
||||||
echo "[n8n-init] Activating workflows..."
|
echo "[n8n-init] Activating workflows..."
|
||||||
|
|||||||
@@ -129,6 +129,5 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"active": false,
|
"active": false,
|
||||||
"settings": { "executionOrder": "v1" },
|
"settings": { "executionOrder": "v1" }
|
||||||
"tags": [{ "name": "parapharmacy" }, { "name": "scraper" }, { "name": "scheduled" }]
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -166,16 +166,5 @@
|
|||||||
"settings": {
|
"settings": {
|
||||||
"executionOrder": "v1"
|
"executionOrder": "v1"
|
||||||
},
|
},
|
||||||
"versionId": "1",
|
"versionId": "1"
|
||||||
"tags": [
|
|
||||||
{
|
|
||||||
"name": "parapharmacy"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "scraper"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "webhook"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -170,13 +170,5 @@
|
|||||||
"settings": {
|
"settings": {
|
||||||
"executionOrder": "v1"
|
"executionOrder": "v1"
|
||||||
},
|
},
|
||||||
"versionId": "1",
|
"versionId": "1"
|
||||||
"tags": [
|
|
||||||
{
|
|
||||||
"name": "parapharmacy"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "scraper"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,6 +94,5 @@
|
|||||||
"Send to API": { "main": [[{ "node": "Format Response", "type": "main", "index": 0 }]] }
|
"Send to API": { "main": [[{ "node": "Format Response", "type": "main", "index": 0 }]] }
|
||||||
},
|
},
|
||||||
"active": true,
|
"active": true,
|
||||||
"settings": { "executionOrder": "v1" },
|
"settings": { "executionOrder": "v1" }
|
||||||
"tags": [{ "name": "parapharmacy" }, { "name": "scraper" }]
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user