@@ -455,11 +455,12 @@ def run(self, invoked_as: str, args: List[str]) -> Tuple[DataFrame, bool]:
455
455
456
456
display (HTML ('\n ' .join (html_buf )))
457
457
else :
458
- # Is a table. Let's go get indices and transform to a dataframe for
459
- # presentation.
460
- index_df = index_dataframe (inspector , relation_name , schema )
461
- if len (index_df ):
462
- display (secondary_dataframe_to_html (index_df ))
458
+ # Is a table. Let's go get indices, foreign keys. If meaningful dataframe returned, transform to
459
+ # HTML for presentation (DEX only expects at most a single DF display()ed per cell) and display it.
460
+ for secondary_function in (index_dataframe , foreignkeys_dataframe ):
461
+ secondary_df = secondary_function (inspector , relation_name , schema )
462
+ if len (secondary_df ):
463
+ display (secondary_dataframe_to_html (secondary_df ))
463
464
464
465
return main_relation_df , False
465
466
@@ -477,6 +478,44 @@ def _split_schema_table(schema_table: str) -> Tuple[Optional[str], str]:
477
478
return (schema , table )
478
479
479
480
481
+ def foreignkeys_dataframe (
482
+ inspector : SchemaStrippingInspector , table_name : str , schema : Optional [str ]
483
+ ) -> DataFrame :
484
+ """Transform results from inspector.get_indexes() into a single dataframe for display() purposes"""
485
+
486
+ names : List [str ] = [] # Will be '(unnamed)' if the constraint was not named
487
+ constrained_columns : List [str ] = [] # Will be comma separated list for compound FKs
488
+ referenced_qualified_tables : List [str ] = []
489
+ referenced_columns : List [str ] = [] # Will be comma separated list for compound FKs
490
+
491
+ fkey_dicts = inspector .get_foreign_keys (table_name , schema )
492
+
493
+ for fk_dict in fkey_dicts :
494
+ if fk_dict ['referred_schema' ]:
495
+ # Schema qualify the table.
496
+ referred_table = f"{ fk_dict ['referred_schema' ]} .{ fk_dict ['referred_table' ]} "
497
+ else :
498
+ referred_table = fk_dict ['referred_table' ]
499
+
500
+ referenced_qualified_tables .append (referred_table )
501
+ names .append (fk_dict .get ('name' , '(unnamed)' ))
502
+ constrained_columns .append (', ' .join (fk_dict .get ('constrained_columns' )))
503
+ referenced_columns .append (', ' .join (fk_dict .get ('referred_columns' )))
504
+
505
+ df = DataFrame (
506
+ {
507
+ 'Foreign Key' : names ,
508
+ 'Columns' : constrained_columns ,
509
+ 'Referenced Table' : referenced_qualified_tables ,
510
+ 'Referenced Columns' : referenced_columns ,
511
+ }
512
+ )
513
+
514
+ title = f'Table <code>{ displayable_relation_name (schema , table_name )} </code> Foreign Keys'
515
+
516
+ return set_dataframe_metadata (df , title = title )
517
+
518
+
480
519
def index_dataframe (
481
520
inspector : SchemaStrippingInspector , table_name : str , schema : Optional [str ]
482
521
) -> DataFrame :
@@ -694,6 +733,9 @@ def get_view_definition(self, view_name: str, schema: Optional[str] = None) -> s
694
733
def get_pk_constraint (self , table_name : str , schema : Optional [str ] = None ) -> dict :
695
734
return self .underlying_inspector .get_pk_constraint (table_name , schema = schema )
696
735
736
+ def get_foreign_keys (self , table_name : str , schema : Optional [str ] = None ) -> List [dict ]:
737
+ return self .underlying_inspector .get_foreign_keys (table_name , schema = schema )
738
+
697
739
def get_indexes (self , table_name : str , schema : Optional [str ] = None ) -> List [dict ]:
698
740
return self .underlying_inspector .get_indexes (table_name , schema = schema )
699
741
0 commit comments