@@ -231,180 +231,62 @@ async def handle_discover_schema(arguments: dict) -> list[types.TextContent]:
231231 return [types .TextContent (type = "text" , text = format_schema_response (current_config ["schema_cache" ]))]
232232
233233 try :
234- from db import run_query
234+ from db import get_table_schema
235235
236- # Try Fabric Data Warehouse compatible schema discovery
237- # First get basic table and column information
238- try :
239- basic_schema_query = """
240- SELECT
241- t.TABLE_SCHEMA,
242- t.TABLE_NAME,
243- t.TABLE_TYPE,
244- c.COLUMN_NAME,
245- c.DATA_TYPE,
246- c.CHARACTER_MAXIMUM_LENGTH,
247- c.NUMERIC_PRECISION,
248- c.NUMERIC_SCALE,
249- c.IS_NULLABLE,
250- c.COLUMN_DEFAULT,
251- c.ORDINAL_POSITION
252- FROM INFORMATION_SCHEMA.TABLES t
253- JOIN INFORMATION_SCHEMA.COLUMNS c ON t.TABLE_NAME = c.TABLE_NAME AND t.TABLE_SCHEMA = c.TABLE_SCHEMA
254- WHERE t.TABLE_TYPE = 'BASE TABLE'
255- AND t.TABLE_SCHEMA NOT IN ('sys', 'INFORMATION_SCHEMA')
256- ORDER BY t.TABLE_SCHEMA, t.TABLE_NAME, c.ORDINAL_POSITION
257- """
258-
259- cols , rows = run_query (basic_schema_query )
260-
261- # Process basic schema data
262- basic_schema_data = {}
263- for row in rows :
264- schema_name = row [0 ]
265- table_name = row [1 ]
266- table_type = row [2 ]
267- column_name = row [3 ]
268- data_type = row [4 ]
269- max_length = row [5 ]
270- precision = row [6 ]
271- scale = row [7 ]
272- is_nullable = row [8 ]
273- default_value = row [9 ]
274- ordinal = row [10 ]
275-
276- full_table_name = f"{ schema_name } .{ table_name } "
277-
278- if full_table_name not in basic_schema_data :
279- basic_schema_data [full_table_name ] = {
280- "schema" : schema_name ,
281- "table_name" : table_name ,
282- "table_type" : table_type ,
283- "columns" : []
284- }
236+ # Use the simplified schema discovery from db.py which handles Fabric compatibility
237+ print ("Starting Fabric-compatible schema discovery..." )
238+ schema_data = get_table_schema ()
239+
240+ if not schema_data :
241+ return [types .TextContent (type = "text" , text = "❌ Schema discovery failed. Please check your connection and permissions." )]
242+
243+ # Convert the schema format to match what the frontend expects
244+ formatted_schema = {}
245+ relationships = [] # No relationships available from basic schema
246+
247+ for table_name , columns in schema_data .items ():
248+ # Split schema.table if present, otherwise assume dbo schema
249+ if '.' in table_name :
250+ schema_name , table_only = table_name .split ('.' , 1 )
251+ else :
252+ schema_name = 'dbo'
253+ table_only = table_name
285254
255+ formatted_schema [table_name ] = {
256+ "schema" : schema_name ,
257+ "table_name" : table_only ,
258+ "table_type" : "BASE TABLE" ,
259+ "columns" : []
260+ }
261+
262+ for col in columns :
286263 col_info = {
287- "name" : column_name ,
288- "data_type" : data_type ,
289- "position" : ordinal ,
290- "is_nullable" : is_nullable == "YES" ,
291- "key_type" : "" # Will be populated separately
264+ "name" : col [ " column_name" ] ,
265+ "data_type" : col [ " data_type" ] ,
266+ "position" : col . get ( "ordinal_position" , 0 ) ,
267+ "is_nullable" : col [ " is_nullable" ] == "YES" ,
268+ "key_type" : "PK" if col . get ( "is_primary_key" , False ) else ""
292269 }
293270
294- if max_length :
295- col_info ["max_length" ] = max_length
296- if precision :
297- col_info ["precision" ] = precision
298- if scale :
299- col_info ["scale" ] = scale
300- if default_value :
301- col_info ["default" ] = default_value
271+ # Add optional column metadata if available
272+ if col .get ("max_length" ):
273+ col_info ["max_length" ] = col ["max_length" ]
274+ if col .get ("numeric_precision" ):
275+ col_info ["precision" ] = col ["numeric_precision" ]
276+ if col .get ("numeric_scale" ):
277+ col_info ["scale" ] = col ["numeric_scale" ]
278+ if col .get ("column_default" ):
279+ col_info ["default" ] = col ["column_default" ]
302280
303- basic_schema_data [full_table_name ]["columns" ].append (col_info )
304-
305- except Exception as e :
306- raise Exception (f"Failed to get basic schema information: { e } " )
307-
308- # Try to get primary key information (separate query for Fabric compatibility)
309- pk_info = {}
310- try :
311- pk_query = """
312- SELECT
313- tc.TABLE_SCHEMA,
314- tc.TABLE_NAME,
315- ku.COLUMN_NAME
316- FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc
317- JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE ku ON tc.CONSTRAINT_NAME = ku.CONSTRAINT_NAME
318- AND tc.TABLE_SCHEMA = ku.TABLE_SCHEMA
319- AND tc.TABLE_NAME = ku.TABLE_NAME
320- WHERE tc.CONSTRAINT_TYPE = 'PRIMARY KEY'
321- """
322-
323- pk_cols , pk_rows = run_query (pk_query )
324-
325- for pk_row in pk_rows :
326- pk_schema = pk_row [0 ]
327- pk_table = pk_row [1 ]
328- pk_column = pk_row [2 ]
329- pk_full_name = f"{ pk_schema } .{ pk_table } "
330-
331- if pk_full_name not in pk_info :
332- pk_info [pk_full_name ] = set ()
333- pk_info [pk_full_name ].add (pk_column )
334-
335- except Exception as pk_e :
336- print (f"Warning: Could not retrieve primary key information: { pk_e } " )
337-
338- # Try to get foreign key information (separate query, may not work in all Fabric configurations)
339- fk_relationships = []
340- try :
341- # Try a simpler FK query that works with more systems
342- fk_query = """
343- SELECT
344- fk.TABLE_SCHEMA as FK_SCHEMA,
345- fk.TABLE_NAME as FK_TABLE,
346- fk.COLUMN_NAME as FK_COLUMN,
347- pk.TABLE_SCHEMA as PK_SCHEMA,
348- pk.TABLE_NAME as PK_TABLE,
349- pk.COLUMN_NAME as PK_COLUMN
350- FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc
351- JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE fk ON rc.CONSTRAINT_NAME = fk.CONSTRAINT_NAME
352- AND rc.CONSTRAINT_SCHEMA = fk.CONSTRAINT_SCHEMA
353- JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE pk ON rc.UNIQUE_CONSTRAINT_NAME = pk.CONSTRAINT_NAME
354- AND rc.UNIQUE_CONSTRAINT_SCHEMA = pk.CONSTRAINT_SCHEMA
355- """
356-
357- fk_cols , fk_rows = run_query (fk_query )
358-
359- fk_info = {}
360- for fk_row in fk_rows :
361- fk_schema = fk_row [0 ]
362- fk_table = fk_row [1 ]
363- fk_column = fk_row [2 ]
364- pk_schema = fk_row [3 ]
365- pk_table = fk_row [4 ]
366- pk_column = fk_row [5 ]
367-
368- fk_full_name = f"{ fk_schema } .{ fk_table } "
369- pk_full_name = f"{ pk_schema } .{ pk_table } "
370-
371- if fk_full_name not in fk_info :
372- fk_info [fk_full_name ] = set ()
373- fk_info [fk_full_name ].add (fk_column )
374-
375- fk_relationships .append ({
376- "from_table" : fk_full_name ,
377- "from_column" : fk_column ,
378- "to_table" : pk_full_name ,
379- "to_column" : pk_column
380- })
381-
382- except Exception as fk_e :
383- print (f"Warning: Could not retrieve foreign key information: { fk_e } " )
384- print ("This is normal for Fabric Data Warehouse - foreign key metadata may not be available" )
385- fk_info = {}
386-
387- # Combine all information
388- schema_data = basic_schema_data
389- for table_name , table_info in schema_data .items ():
390- table_pks = pk_info .get (table_name , set ())
391- table_fks = fk_info .get (table_name , set ())
392-
393- for col in table_info ["columns" ]:
394- if col ["name" ] in table_pks :
395- col ["key_type" ] = "PK"
396- elif col ["name" ] in table_fks :
397- col ["key_type" ] = "FK"
398- else :
399- col ["key_type" ] = ""
281+ formatted_schema [table_name ]["columns" ].append (col_info )
400282
401283 # Cache the schema
402284 current_config ["schema_cache" ] = {
403- "tables" : schema_data ,
404- "relationships" : fk_relationships ,
285+ "tables" : formatted_schema ,
286+ "relationships" : relationships ,
405287 "discovered_at" : asyncio .get_event_loop ().time ()
406- }
407-
288+ }
289+
408290 return [types .TextContent (type = "text" , text = format_schema_response (current_config ["schema_cache" ]))]
409291
410292 except Exception as e :
0 commit comments