mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-01-27 16:57:00 -06:00
Add support for generating ERD for a schema. #4580
This commit is contained in:
parent
c9590b2d62
commit
377216caec
@ -18,7 +18,14 @@ The Entity-Relationship Diagram (ERD) tool is a database design tool that provid
|
||||
:alt: ERD tool window
|
||||
:align: center
|
||||
|
||||
You can open multiple copies of the ERD tool in individual tabs simultaneously. To close a copy of the ERD tool, click the *X* in the upper-right hand corner of the tab bar.
|
||||
You can open multiple copies of the ERD tool in individual tabs simultaneously.
|
||||
You can also generate an ERD from a database, schema or a table.
|
||||
|
||||
* The ERD for database will fetch all the tables from all the schemas of the database and plot them with foreign key links.
|
||||
* The ERD for schema will fetch all the tables from a schema and plot them with foreign key links. If any table refers to a table in another
|
||||
schema, then that link/foreign key will be removed.
|
||||
* The ERD for table will fetch all the tables linked directly or indirectly to mentioned table. You can change the depth of traversal from :ref:`Preferences <preferences>`.
|
||||
|
||||
|
||||
Toolbar
|
||||
*******
|
||||
|
@ -13,8 +13,8 @@ import { getNodeListByName } from '../../../../../../static/js/node_ajax';
|
||||
|
||||
define('pgadmin.node.schema', [
|
||||
'sources/gettext', 'sources/url_for',
|
||||
'pgadmin.browser', 'pgadmin.browser.collection',
|
||||
], function(gettext, url_for, pgBrowser) {
|
||||
'sources/pgadmin', 'pgadmin.browser', 'pgadmin.browser.collection',
|
||||
], function(gettext, url_for, pgAdmin, pgBrowser) {
|
||||
|
||||
// Extend the browser's collection class for schema collection
|
||||
if (!pgBrowser.Nodes['coll-schema']) {
|
||||
@ -61,12 +61,25 @@ define('pgadmin.node.schema', [
|
||||
applies: ['object', 'context'], callback: 'show_obj_properties',
|
||||
category: 'create', priority: 1, label: gettext('Schema...'),
|
||||
data: {action: 'create'}, enable: 'can_create_schema',
|
||||
},
|
||||
]);
|
||||
},{
|
||||
name: 'generate_erd', node: 'schema', module: this,
|
||||
applies: ['object', 'context'], callback: 'generate_erd',
|
||||
category: 'erd', priority: 5, label: gettext('ERD For Schema')
|
||||
}]);
|
||||
},
|
||||
can_create_schema: function(node) {
|
||||
return pgBrowser.Nodes['database'].is_conn_allow.call(this, node);
|
||||
},
|
||||
callbacks: {
|
||||
/* Generate the ERD */
|
||||
generate_erd: function(args) {
|
||||
let input = args || {},
|
||||
t = pgBrowser.tree,
|
||||
i = input.item || t.selected(),
|
||||
d = i ? t.itemData(i) : undefined;
|
||||
pgAdmin.Tools.ERD.showErdTool(d, i, true);
|
||||
},
|
||||
},
|
||||
getSchema: function(treeNodeInfo, itemNodeData) {
|
||||
let schemaObj = pgBrowser.Nodes['schema'];
|
||||
return new PGSchema(
|
||||
|
@ -131,9 +131,11 @@ export default class ERDModule {
|
||||
+`&did=${parentData.database._id}`
|
||||
+`&gen=${gen}`;
|
||||
|
||||
if(parentData.schema) {
|
||||
openUrl += `&scid=${parentData.schema._id}`;
|
||||
}
|
||||
if(parentData.table) {
|
||||
openUrl += `&scid=${parentData.schema._id}`
|
||||
+`&tid=${parentData.table._id}`;
|
||||
openUrl += `&tid=${parentData.table._id}`;
|
||||
}
|
||||
|
||||
return openUrl;
|
||||
|
@ -615,7 +615,7 @@ export default class ERDCore {
|
||||
_.forIn(tableNodesDict, (node, uid)=>{
|
||||
let nodeData = node.getData();
|
||||
if(nodeData.foreign_key) {
|
||||
nodeData.foreign_key.forEach((theFk)=>{
|
||||
nodeData.foreign_key = nodeData.foreign_key.filter((theFk)=>{
|
||||
delete theFk.oid;
|
||||
theFk = theFk.columns[0];
|
||||
theFk.references = oidUidMap[theFk.references];
|
||||
@ -627,11 +627,17 @@ export default class ERDCore {
|
||||
};
|
||||
let sourceNode = tableNodesDict[newData.referenced_table_uid];
|
||||
let targetNode = tableNodesDict[newData.local_table_uid];
|
||||
// When generating for schema, there may be a reference to another schema table
|
||||
// We'll remove the FK completely in such cases.
|
||||
if(!sourceNode || !targetNode) {
|
||||
return false;
|
||||
}
|
||||
|
||||
newData.local_column_attnum = _.find(targetNode.getColumns(), (col)=>col.name==theFk.local_column).attnum;
|
||||
newData.referenced_column_attnum = _.find(sourceNode.getColumns(), (col)=>col.name==theFk.referenced).attnum;
|
||||
|
||||
this.addLink(newData, 'onetomany');
|
||||
return true;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -32,12 +32,16 @@ class ERDTableView(BaseTableView, DataTypeReader):
|
||||
return DataTypeReader.get_types(self, self.conn, condition, True)
|
||||
|
||||
@BaseTableView.check_precondition
|
||||
def fetch_all_tables(self, did=None, sid=None):
|
||||
status, schemas = get_schemas(self.conn, show_system_objects=False)
|
||||
if not status:
|
||||
return status, schemas
|
||||
|
||||
def fetch_all_tables(self, did=None, sid=None, scid=None):
|
||||
all_tables = []
|
||||
schemas = {'rows': []}
|
||||
if scid is None:
|
||||
status, schemas = get_schemas(self.conn, show_system_objects=False)
|
||||
if not status:
|
||||
return status, schemas
|
||||
else:
|
||||
schemas['rows'].append({'oid': scid})
|
||||
|
||||
for row in schemas['rows']:
|
||||
status, res = \
|
||||
BaseTableView.fetch_tables(self, sid, did, row['oid'],
|
||||
@ -111,6 +115,9 @@ class ERDHelper:
|
||||
if tid is None and scid is None:
|
||||
status, res = self.table_view.fetch_all_tables(
|
||||
did=self.did, sid=self.sid)
|
||||
elif tid is None:
|
||||
status, res = self.table_view.fetch_all_tables(
|
||||
did=self.did, sid=self.sid, scid=scid)
|
||||
else:
|
||||
prefs = Preferences.module('erd')
|
||||
table_relation_depth = prefs.preference('table_relation_depth')
|
||||
|
Loading…
Reference in New Issue
Block a user