Consistent duplicate constraints/working in tools, prompts and resources#2507
Consistent duplicate constraints/working in tools, prompts and resources#2507crivetimihai merged 1 commit intomainfrom
Conversation
brian-hussey
left a comment
There was a problem hiding this comment.
The code is fine, I've suggested a couple of changes from a readability point of view.
I tested the DB upgrade and downgrade path to this from rev this-2 to this-1 and this, and then back down to -1 and -2 and everything worked well.
|
Hi @brian-hussey, Since we use |
|
@kevalmahajan Tested the fix in local, and seems to be working fine. |
Ah cool, thanks. I'll resolve the conversation so. |
brian-hussey
left a comment
There was a problem hiding this comment.
Tested changes locally, up 2 versions to this and down 2 versions.
Everything worked as expected.
7b9ed73 to
a526ea8
Compare
Changes Made During Review1. Rebased onto main
2. Fixed Migration Idempotency (Critical)The original migration was not idempotent and would fail when:
Changes made:
3. Code Review SummaryDesign is sound:
No security issues identified. No performance concerns - constraint changes are schema-level. Ready for TestingPlease run: make test |
a526ea8 to
9bcd4d9
Compare
Additional Fixes (v2)Addressed remaining issues: 1. Fixed exception handling in
|
| Issue | Fix |
|---|---|
| Introspection failure skipped creates | Return False → attempt create, catch errors |
| Early return skipped prompts | Independent helper functions for each table |
| All operations | Wrapped in try/except for graceful handling |
Ready for testing: make test
Updates unique constraints for Resources and Prompts tables to support Gateway-level namespacing. Previously, these entities enforced uniqueness globally per Team/Owner (team_id, owner_email, uri/name). This prevented users from registering the same Gateway multiple times with different names. Changes: - Add gateway_id to unique constraints for resources and prompts - Add partial unique indexes for local items (where gateway_id IS NULL) - Make migration idempotent with proper existence checks Closes #2352 Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
9bcd4d9 to
c0e20dd
Compare
Final Review Complete ✅Changes Made
Code Quality
Follow-upRegression tests for the new constraint behavior tracked in #2520 Ready to MergeThe PR is ready for final approval and merge. |
Additional Follow-up IssueCreated #2522 to track the silent exception handling concern in the migration. The current implementation swallows all exceptions which could mask real schema failures. Recommendation: Address #2522 before deploying to production environments where migration failures need to be surfaced. |
✅ Manual Database Constraint TestingTested the implementation against a running PostgreSQL instance via docker-compose. Verified ConstraintsResources table: SELECT conname, pg_get_constraintdef(oid) FROM pg_constraint WHERE conrelid = 'resources'::regclass AND contype = 'u';
conname | pg_get_constraintdef
------------------------------------+------------------------------------------------
uq_team_owner_gateway_uri_resource | UNIQUE (team_id, owner_email, gateway_id, uri)SELECT indexname, indexdef FROM pg_indexes WHERE tablename = 'resources' AND indexname LIKE '%local%';
indexname | indexdef
----------------------------------+-----------------------------------------------------------------------------
uq_team_owner_uri_resource_local | CREATE UNIQUE INDEX ... WHERE (gateway_id IS NULL)Prompts table: Same pattern verified ✅ Test Results
How to Reproduce# Start the stack
docker compose up -d
# Connect to PostgreSQL
docker exec mcp-context-forge-postgres-1 psql -U postgres -d mcp
# Run test queries (see above)ConclusionThe gateway namespacing constraints are working correctly:
|
IBM#2507) Updates unique constraints for Resources and Prompts tables to support Gateway-level namespacing. Previously, these entities enforced uniqueness globally per Team/Owner (team_id, owner_email, uri/name). This prevented users from registering the same Gateway multiple times with different names. Changes: - Add gateway_id to unique constraints for resources and prompts - Add partial unique indexes for local items (where gateway_id IS NULL) - Make migration idempotent with proper existence checks Closes IBM#2352 Signed-off-by: Mihai Criveti <crivetimihai@gmail.com> Signed-off-by: hughhennnelly <hughhennelly06@gmail.com>
IBM#2507) Updates unique constraints for Resources and Prompts tables to support Gateway-level namespacing. Previously, these entities enforced uniqueness globally per Team/Owner (team_id, owner_email, uri/name). This prevented users from registering the same Gateway multiple times with different names. Changes: - Add gateway_id to unique constraints for resources and prompts - Add partial unique indexes for local items (where gateway_id IS NULL) - Make migration idempotent with proper existence checks Closes IBM#2352 Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
🐛 Bug-fix PR
Closes #2352
Reference: (Continuation of #2351)
📌 Summary
Updates the unique constraints for Resources and Prompts tables to support Gateway-level namespacing. Previously, these entities enforced uniqueness globally per Team/Owner (team_id, owner_email, uri/name). This prevented users from registering the same Gateway (e.g., using one-time auth) multiple times with different names, as the Resources/Prompts would collide.
This adds consistency with the working of tools, prompts and resources.
Handles both scenarios, prompts and resources added with gateway and without gateway/directly.
🔁 Reproduction Steps
🐞 Root Cause
Database Schema: The Resource table had a unique constraint on (team_id, owner_email, uri). The Prompt table had a unique constraint on (team_id, owner_email, name).
Logic: When a second Gateway attempted to sync the same Resources/Prompts, it tried to insert records with the same identifier for the same Team/Owner. Unlike Tools, which compute a namespaced name, Resources/Prompts utilize their raw identifiers, causing a collision at the database level.
💡 Fix Description
1. Updated Constraints: Modified
mcpgateway/db.pyto replace the restrictive team-level constraints with composite constraints that include gateway_id.3. Migration: Added a new Alembic migration script (b1b2b3b4b5b6_fix_constraints.py) to apply these schema changes.
4. Result:
🧪 Verification
make lintmake testmake coverage📐 MCP Compliance (if relevant)
✅ Checklist
make black isort pre-commit)