-
Notifications
You must be signed in to change notification settings - Fork 824
ERD Tool: Insert table with relations via drag-and-drop #9581
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
ERD Tool: Insert table with relations via drag-and-drop #9581
Conversation
Co-authored-by: Christian P. <[email protected]>
WalkthroughThis change adds functionality to automatically include related tables when dragging and dropping tables into an ERD diagram. It introduces a new preference flag, extends table schema data extraction with OID support, and implements centralized foreign key link creation logic with a two-phase deserialization flow. Changes
Sequence DiagramsequenceDiagram
actor User
participant ERDTool as ERDTool.jsx
participant API as Backend API
participant ERDCore
participant Canvas as Diagram
User->>ERDTool: Drag & drop table
ERDTool->>API: Fetch table data with ERD schema
API-->>ERDTool: Return table + original_foreign_keys
alt insert_table_with_relations enabled
ERDTool->>ERDCore: addNodeWithLinks(data, position)
ERDCore->>ERDCore: Create node from table data
ERDCore->>ERDCore: Build oid-to-uid map
ERDCore->>ERDCore: addLinksBetweenNodes(oidUidMap)
ERDCore->>ERDCore: Resolve & create FK links
ERDCore->>Canvas: Render node + FK links
else insert_table_with_relations disabled
ERDTool->>ERDCore: addNode(cloneTableData, position)
ERDCore->>Canvas: Render node (no auto-links)
end
ERDTool->>Canvas: Select created node
Canvas-->>User: Display table with/without relations
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested reviewers
🚥 Pre-merge checks | ✅ 5 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@web/pgadmin/tools/erd/static/js/erd_tool/components/ERDTool.jsx`:
- Around line 599-618: The catch block for the API call in the apiObj.get(...)
chain currently only logs and rethrows, causing silent failures; replace the
console.error/throw in that catch with a call to the component's existing error
handler (e.g. this.handleAxiosCatch(err) or the notifier used elsewhere) to
surface the failure to users and remove the rethrow so the promise is handled;
update the catch for apiObj.get(...) where TableSchema.getErdSupportedData and
addNode/addNodeWithLinks are invoked to call handleAxiosCatch(err) instead of
console.error/throw.
In `@web/pgadmin/tools/erd/static/js/erd_tool/nodes/TableNode.jsx`:
- Around line 161-165: serializeData() is mutating the node's live data by
filtering data.foreign_key in-place which can permanently remove FKs; fix by
cloning the data (or at least the foreign_key array) returned from getData()
before applying the filter so the node's persisted state remains unchanged —
e.g., obtain const data = this.getData(); create a shallow copy (or copy of
data.foreign_key) and run the .filter on that copy, then return the
cloned/modified copy while leaving the original getData() object intact.
🧹 Nitpick comments (1)
web/pgadmin/tools/erd/static/js/erd_tool/ERDCore.js (1)
686-724: Guard against missing FK column metadata during link creation.
addLinksBetweenNodesassumesfk.columns[0]and column lookups always resolve. A malformed FK or a column removed in the ERD could throw here and break drag‑and‑drop. A small guard keeps this path resilient.🛡️ Suggested defensive checks
- const theFkColumn = theFk.columns[0]; + const theFkColumn = theFk.columns?.[0]; + if (!theFkColumn) return; let referencesUid = oidUidMap[theFkColumn.references_oid]; @@ - const newData = { - local_table_uid: uid, - local_column_attnum: _.find( - tableNodesDict[uid].getColumns(), - (col) => col.name == theFkColumn.local_column - ).attnum, - referenced_table_uid: referencesUid, - referenced_column_attnum: _.find( - tableNodesDict[referencesUid].getColumns(), - (col) => col.name == theFkColumn.referenced - ).attnum, - }; + const localCol = _.find( + tableNodesDict[uid].getColumns(), + (col) => col.name == theFkColumn.local_column + ); + const refCol = _.find( + tableNodesDict[referencesUid].getColumns(), + (col) => col.name == theFkColumn.referenced + ); + if (!localCol || !refCol) return; + const newData = { + local_table_uid: uid, + local_column_attnum: localCol.attnum, + referenced_table_uid: referencesUid, + referenced_column_attnum: refCol.attnum, + };
|
We were unsure how to update the translations, thus skipped that for now |
|
Hi @Lancear, I tested the PR and identified the following issues:
|
|
1 was intentional so the ERD diagram matches the generated SQL and has no additional foreign keys. I think we can change 1 by separating the original foreign keys from the schema, from the ones drawn in the ER diagram, will check it out. Will do both of these on Thursday when I have more time in the evening. |
9ab5f69 to
ccd894a
Compare
Co-authored-by: Christian P. <[email protected]>
ccd894a to
2cace1c
Compare
|
Addressed both issues |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In `@web/pgadmin/tools/erd/static/js/erd_tool/ERDCore.js`:
- Around line 702-708: The duplicate-link guard in addNodeWithLinks only checks
newNodesUids and misses existing visual links, so update the check (around the
block using newNodesUids, uid and referencesUid) to also detect and skip if a
link between uid and referencesUid already exists before calling addLink;
specifically, query the current links collection (e.g., this.links /
graph.getLinks() or the structure that stores links) and if any link has source
=== uid and target === referencesUid (or vice‑versa if links are undirected),
return/skip adding; ensure the check uses the same identifier fields that
addLink expects so duplicates are never created.
- Around line 692-726: The loop that processes nodeData.original_foreign_keys
must guard against missing pieces: ensure theFk.columns && theFk.columns[0]
exists, initialize nodeData.foreign_key if falsy, and check the _.find(...)
results before accessing .attnum; if either the local column lookup or the
referenced column lookup returns undefined (or referencesUid is missing) then
skip this FK (do not push to nodeData.foreign_key or call this.addLink).
Concretely, in the block handling theFk use a guard like: if (!theFk.columns ||
!theFk.columns[0]) return; set nodeData.foreign_key = nodeData.foreign_key ||
[]; resolve localCol = _.find(tableNodesDict[uid].getColumns(), ...) and refCol
= _.find(tableNodesDict[referencesUid].getColumns(), ...); if (!localCol ||
!refCol) return; then build newData using localCol.attnum and refCol.attnum,
clone theFk, set newForeignKey.columns[0].references = referencesUid, push to
nodeData.foreign_key and call this.addLink.
- Around line 660-666: The function addNodeWithLinks currently calls delete
nodeData.oid which mutates the caller's object; instead make a shallow clone or
destructure at the start (e.g., const node = { ...nodeData } or const { oid,
...node } = nodeData) and operate on that local copy (delete node.oid or use the
destructured node) so you never modify the original nodeData; update all
subsequent references in addNodeWithLinks to use the local cloned variable
(node) and leave nodeData untouched.

Feature: Drag and Drop Tables with Relations in ERD
This feature allows tables to be dragged into the ERD tool along with their foreign key relationships automatically.
Closes #5578
Closes #8198
Key Decisions
Keep original
oidand a copy offoreign_keyin nodesPreserves table identity and allows checking future references. Only the first node with each
oidretains theoid.First instance priority
Only the first insert of a table is checked for incoming references from other nodes, preventing duplicate foreign key links.
File save preserves all original foreign keys
Missing table references are kept when saving, allowing users to add the referenced tables later.
User preference added
New preference "Drag and Drop table with relations" to control this behavior, default acts like before.
Co-authored-by: Christian P. [email protected]
Summary by CodeRabbit
New Features
Bug Fixes
✏️ Tip: You can customize this high-level summary in your review settings.