2
2
3
3
import pathlib
4
4
import re
5
+ import sys
5
6
import time
6
7
from concurrent .futures import ThreadPoolExecutor , as_completed
7
- import sys
8
+ from datetime import datetime
8
9
from typing import Any , Dict , Iterable , List , Optional , Tuple
9
10
from uuid import UUID
10
11
@@ -541,6 +542,12 @@ def run(self, invoked_as: str, args: List[str]) -> None:
541
542
542
543
inspector = self .get_inspector ()
543
544
545
+ # On successful completion, will tell Gate to delete any now-orphaned
546
+ # relations from prior introspections older than this timestamp.
547
+ introspection_started_at = datetime .utcnow ()
548
+
549
+ # This and delta() just for development timing figures. Could become yet another
550
+ # timer context manager implementation.
544
551
start = time .monotonic ()
545
552
546
553
def delta () -> float :
@@ -600,12 +607,15 @@ def delta() -> float:
600
607
session .headers .update (auth_header )
601
608
602
609
if message_queue :
603
- # Clear out any prior known relations for this datasource.
604
- self .inform_gate_start (session , ds_id )
605
-
606
610
for message in message_queue :
607
611
self .inform_gate_relation (session , ds_id , message )
608
612
613
+ # Clear out any prior known relations which may not exist anymore in this datasource.
614
+ #
615
+ # We do this at the tail end of things, and not the beginning, so as to not eagerly delete
616
+ # prior known data if we happen to croak due to some unforseen exception while introspecting.
617
+ self .inform_gate_completed (session , ds_id , introspection_started_at )
618
+
609
619
print (f'Done storing discovered table and view structures in { delta ()} ' )
610
620
611
621
# run() contract: return what to bind to the SQL cell variable name, and if display() needs
@@ -821,14 +831,6 @@ def introspect_columns(
821
831
822
832
return retlist
823
833
824
- def inform_gate_start (self , session : requests .Session , datasource_id : UUID ):
825
- """Tell gate to forget about any prior structures known for this datasource"""
826
-
827
- # No route implemented for this yet, but need one, otherwise Gate-side will
828
- # never forget about dropped tables/views.
829
-
830
- pass
831
-
832
834
def inform_gate_relation (
833
835
self ,
834
836
session : requests .Session ,
@@ -851,6 +853,16 @@ def inform_gate_relation(
851
853
f'Failed storing structure of { relation_description .schema_name } .{ relation_description .relation_name } : { resp .status_code } , { resp .text } '
852
854
)
853
855
856
+ def inform_gate_completed (
857
+ self , session : requests .Session , datasource_id : UUID , started_at : datetime
858
+ ):
859
+ """Tell gate to forget about any structures known for this datasource older than when we
860
+ started this introspection run."""
861
+
862
+ session .delete (
863
+ f"http://gate.default/api/v1/datasources/{ datasource_id } /schema/relations?older_than={ started_at .isoformat ()} "
864
+ )
865
+
854
866
def get_datasource_id (self ) -> UUID :
855
867
"""Convert a noteable_magics.sql.connection.Connection's name to the original
856
868
UUID Gate knew it as.
0 commit comments