1818
1919
2020class Dlist (list ):
21- """Service class for convenient work with list of dicts(db response)"""
21+ """Service class for convenient work with list of dicts(db response).
22+ Assumes keys are already normalized to lowercase."""
2223
2324 def __contains__ (self , item ):
2425 if len (self ) == 0 :
@@ -59,7 +60,7 @@ def query(self, _query, encoding="utf-8", with_description=False):
5960
6061 if cursor .description :
6162 description = cursor .description
62- columns = [i [0 ] for i in cursor .description ]
63+ columns = [i [0 ]. lower () for i in cursor .description ]
6364 data = cursor .fetchall ()
6465
6566 res = Dlist ()
@@ -91,27 +92,29 @@ def upload_ds(self, df, name):
9192
9293 with open (filename , "r" ) as f :
9394 url = f"{ HTTP_API_ROOT } /files/{ name } "
94- data = {"name " : (name , f , "text/csv" )}
95- res = requests .put (url , files = data )
95+ files = {"file " : (f" { name } .csv" , f , "text/csv" )}
96+ res = requests .put (url , files = files )
9697 res .raise_for_status ()
9798
9899 def verify_file_ds (self , ds_name ):
99- timeout = 5
100+ timeout = 10
100101 threshold = time .time () + timeout
101102 res = ""
102103 while time .time () < threshold :
103104 res = self .query ("SHOW tables from files;" )
104- if "Tables_in_files " in res and res .get_record ("Tables_in_files " , ds_name ):
105- break
106- time .sleep (0.5 )
107- assert "Tables_in_files " in res and res .get_record ("Tables_in_files " , ds_name ), (
105+ if "tables_in_files " in res and res .get_record ("tables_in_files " , ds_name ):
106+ return
107+ time .sleep (0.3 )
108+ assert "tables_in_files " in res and res .get_record ("tables_in_files " , ds_name ), (
108109 f"file datasource { ds_name } is not ready to use after { timeout } seconds"
109110 )
110111
111112 def check_predictor_readiness (self , predictor_name ):
112113 timeout = 600
113114 threshold = time .time () + timeout
114115 res = ""
116+ model_not_found_threshold = time .time () + 30
117+ check_interval = 1
115118 while time .time () < threshold :
116119 _query = "SELECT status, error FROM mindsdb.models WHERE name='{}';" .format (predictor_name )
117120 res = self .query (_query )
@@ -120,9 +123,11 @@ def check_predictor_readiness(self, predictor_name):
120123 break
121124 elif res .get_record ("status" , "error" ):
122125 raise Exception (res [0 ]["error" ])
123- time .sleep (2 )
126+ elif len (res ) == 0 and time .time () > model_not_found_threshold :
127+ raise Exception (f"Model { predictor_name } not found in models table after 30 seconds" )
128+ time .sleep (check_interval )
124129 assert "status" in res and res .get_record ("status" , "complete" ), (
125- f"predictor { predictor_name } is not complete after { timeout } seconds"
130+ f"predictor { predictor_name } is not complete after { timeout } seconds. Last result: { res } "
126131 )
127132
128133 def validate_database_creation (self , name ):
@@ -454,21 +459,21 @@ def test_show_columns(self, use_binary):
454459 """ )
455460 assert len (ret ) == 8
456461 # TODO FIX STR->INT casting
457- # assert sorted([x['ORDINAL_POSITION '] for x in ret]) == list(range(1, 9))
458-
459- rental_price_column = next (x for x in ret if x ["COLUMN_NAME" ]. lower () == "rental_price" )
460- assert rental_price_column ["DATA_TYPE " ] == "int"
461- assert rental_price_column ["COLUMN_TYPE " ] == "int"
462- assert rental_price_column ["ORIGINAL_TYPE " ] == "integer"
463- assert rental_price_column ["NUMERIC_PRECISION " ] is not None
464-
465- location_column = next (x for x in ret if x ["COLUMN_NAME" ]. lower () == "location" )
466- assert location_column ["DATA_TYPE " ] == "varchar"
467- assert location_column ["COLUMN_TYPE " ].startswith ("varchar(" ) # varchar(###)
468- assert location_column ["ORIGINAL_TYPE " ] == "character varying"
469- assert location_column ["NUMERIC_PRECISION " ] is None
470- assert location_column ["CHARACTER_MAXIMUM_LENGTH " ] is not None
471- assert location_column ["CHARACTER_OCTET_LENGTH " ] is not None
462+ # assert sorted([x['ordinal_position '] for x in ret]) == list(range(1, 9))
463+
464+ rental_price_column = next (x for x in ret if x ["column_name" ] == "rental_price" )
465+ assert rental_price_column ["data_type " ] == "int"
466+ assert rental_price_column ["column_type " ] == "int"
467+ assert rental_price_column ["original_type " ] == "integer"
468+ assert rental_price_column ["numeric_precision " ] is not None
469+
470+ location_column = next (x for x in ret if x ["column_name" ] == "location" )
471+ assert location_column ["data_type " ] == "varchar"
472+ assert location_column ["column_type " ].startswith ("varchar(" ) # varchar(###)
473+ assert location_column ["original_type " ] == "character varying"
474+ assert location_column ["numeric_precision " ] is None
475+ assert location_column ["character_maximum_length " ] is not None
476+ assert location_column ["character_octet_length " ] is not None
472477
473478 def test_train_model_from_files (self , use_binary ):
474479 df = pd .DataFrame (
0 commit comments