66
77from __future__ import annotations
88
9+ import logging
10+ from contextlib import suppress
911from typing import Any , cast
1012
1113from sqlalchemy import types as sa_types
2830 "TIMESTAMP" : sa_types .DateTime ,
2931}
3032
33+ _LOG = logging .getLogger (__name__ )
34+
3135
3236def _sa_type_from_name (type_name : str ) -> sa_types .TypeEngine [Any ]:
3337 """Convert an excel-dbapi type name to a SQLAlchemy type instance."""
@@ -51,6 +55,9 @@ def get_table_names(
5155 """Return all worksheet names, excluding the metadata sheet."""
5256 import excel_dbapi
5357
58+ if schema is not None :
59+ return []
60+
5461 raw_conn = connection .connection .dbapi_connection
5562 return cast ("list[str]" , excel_dbapi .list_tables (raw_conn , include_meta = False ))
5663
@@ -77,6 +84,9 @@ def get_columns(
7784 """
7885 import excel_dbapi
7986
87+ if schema is not None :
88+ raise NoSuchTableError (table_name )
89+
8090 raw_conn = self ._raw_connection (connection )
8191 table_exists = cast ("bool" , excel_dbapi .has_table (raw_conn , table_name ))
8292 if not table_exists :
@@ -123,6 +133,9 @@ def get_pk_constraint(
123133 """Return primary key constraint info from the metadata sheet."""
124134 import excel_dbapi
125135
136+ if schema is not None :
137+ raise NoSuchTableError (table_name )
138+
126139 raw_conn = self ._raw_connection (connection )
127140 table_exists = cast ("bool" , excel_dbapi .has_table (raw_conn , table_name ))
128141 if not table_exists :
@@ -147,6 +160,8 @@ def get_foreign_keys(
147160 ** kw : Any ,
148161 ) -> list [dict [str , Any ]]:
149162 """Excel does not support foreign keys."""
163+ if schema is not None :
164+ raise NoSuchTableError (table_name )
150165 self ._assert_table_exists (connection , table_name )
151166 return []
152167
@@ -158,6 +173,8 @@ def get_indexes(
158173 ** kw : Any ,
159174 ) -> list [dict [str , Any ]]:
160175 """Excel does not support indexes."""
176+ if schema is not None :
177+ raise NoSuchTableError (table_name )
161178 self ._assert_table_exists (connection , table_name )
162179 return []
163180
@@ -169,6 +186,8 @@ def get_unique_constraints(
169186 ** kw : Any ,
170187 ) -> list [dict [str , Any ]]:
171188 """Excel does not support unique constraints."""
189+ if schema is not None :
190+ raise NoSuchTableError (table_name )
172191 self ._assert_table_exists (connection , table_name )
173192 return []
174193
@@ -180,6 +199,8 @@ def get_check_constraints(
180199 ** kw : Any ,
181200 ) -> list [dict [str , Any ]]:
182201 """Excel does not support check constraints."""
202+ if schema is not None :
203+ raise NoSuchTableError (table_name )
183204 self ._assert_table_exists (connection , table_name )
184205 return []
185206
@@ -191,6 +212,8 @@ def get_table_comment(
191212 ** kw : Any ,
192213 ) -> dict [str , Any ]:
193214 """Excel does not support table comments."""
215+ if schema is not None :
216+ raise NoSuchTableError (table_name )
194217 self ._assert_table_exists (connection , table_name )
195218 return {"text" : None }
196219
@@ -208,9 +231,33 @@ def _metadata_header_matches(
208231 header_names : list [str ] | None ,
209232 ) -> bool :
210233 if header_names is None :
211- return True
234+ return False
212235 return [col ["name" ] for col in meta ] == header_names
213236
237+ @staticmethod
238+ def _cursor_header_names (raw_conn : Any , table_name : str ) -> list [str ] | None :
239+ try :
240+ cursor = raw_conn .cursor ()
241+ except Exception :
242+ return None
243+
244+ try :
245+ cursor .execute (f"SELECT * FROM { table_name } LIMIT 0" )
246+ description = getattr (cursor , "description" , None )
247+ if not description :
248+ return None
249+ header_names = [
250+ str (column [0 ])
251+ for column in description
252+ if column is not None and column [0 ] is not None
253+ ]
254+ return header_names or None
255+ except Exception :
256+ return None
257+ finally :
258+ with suppress (Exception ):
259+ cursor .close ()
260+
214261 def _validated_metadata (
215262 self ,
216263 raw_conn : Any ,
@@ -223,6 +270,15 @@ def _validated_metadata(
223270 if meta is None :
224271 return None
225272
273+ if header_names is None :
274+ header_names = self ._cursor_header_names (raw_conn , table_name )
275+ if header_names is None :
276+ _LOG .warning (
277+ "Could not validate metadata headers for table '%s'; using stored metadata" ,
278+ table_name ,
279+ )
280+ return meta
281+
226282 if not self ._metadata_header_matches (meta , header_names ):
227283 excel_dbapi .remove_table_metadata (raw_conn , table_name )
228284 return None
0 commit comments