thoth-dbmanager 0.4.0__py3-none-any.whl → 0.4.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- thoth_dbmanager/ThothDbManager.py +459 -0
- thoth_dbmanager/__init__.py +136 -0
- thoth_dbmanager/adapters/__init__.py +21 -0
- thoth_dbmanager/adapters/mariadb.py +165 -0
- thoth_dbmanager/adapters/mysql.py +165 -0
- thoth_dbmanager/adapters/oracle.py +554 -0
- thoth_dbmanager/adapters/postgresql.py +444 -0
- thoth_dbmanager/adapters/sqlite.py +385 -0
- thoth_dbmanager/adapters/sqlserver.py +583 -0
- thoth_dbmanager/adapters/supabase.py +249 -0
- thoth_dbmanager/core/__init__.py +13 -0
- thoth_dbmanager/core/factory.py +272 -0
- thoth_dbmanager/core/interfaces.py +271 -0
- thoth_dbmanager/core/registry.py +220 -0
- thoth_dbmanager/documents.py +155 -0
- thoth_dbmanager/dynamic_imports.py +250 -0
- thoth_dbmanager/helpers/__init__.py +0 -0
- thoth_dbmanager/helpers/multi_db_generator.py +508 -0
- thoth_dbmanager/helpers/preprocess_values.py +159 -0
- thoth_dbmanager/helpers/schema.py +376 -0
- thoth_dbmanager/helpers/search.py +117 -0
- thoth_dbmanager/lsh/__init__.py +21 -0
- thoth_dbmanager/lsh/core.py +182 -0
- thoth_dbmanager/lsh/factory.py +76 -0
- thoth_dbmanager/lsh/manager.py +170 -0
- thoth_dbmanager/lsh/storage.py +96 -0
- thoth_dbmanager/plugins/__init__.py +23 -0
- thoth_dbmanager/plugins/mariadb.py +436 -0
- thoth_dbmanager/plugins/mysql.py +408 -0
- thoth_dbmanager/plugins/oracle.py +150 -0
- thoth_dbmanager/plugins/postgresql.py +145 -0
- thoth_dbmanager/plugins/sqlite.py +170 -0
- thoth_dbmanager/plugins/sqlserver.py +149 -0
- thoth_dbmanager/plugins/supabase.py +224 -0
- {thoth_dbmanager-0.4.0.dist-info → thoth_dbmanager-0.4.1.dist-info}/METADATA +6 -6
- thoth_dbmanager-0.4.1.dist-info/RECORD +39 -0
- thoth_dbmanager-0.4.1.dist-info/top_level.txt +1 -0
- thoth_dbmanager-0.4.0.dist-info/RECORD +0 -5
- thoth_dbmanager-0.4.0.dist-info/top_level.txt +0 -1
- {thoth_dbmanager-0.4.0.dist-info → thoth_dbmanager-0.4.1.dist-info}/WHEEL +0 -0
- {thoth_dbmanager-0.4.0.dist-info → thoth_dbmanager-0.4.1.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,459 @@
|
|
1
|
+
import pickle
|
2
|
+
import logging
|
3
|
+
from abc import ABC, abstractmethod
|
4
|
+
from pathlib import Path
|
5
|
+
from threading import Lock
|
6
|
+
from typing import Any, Dict, List, Optional, Union, ClassVar, Type, TypeVar
|
7
|
+
|
8
|
+
from .lsh.manager import LshManager
|
9
|
+
from .core.factory import ThothDbFactory
|
10
|
+
from .core.interfaces import DbPlugin
|
11
|
+
|
12
|
+
# Import plugins to register them
|
13
|
+
from .plugins.postgresql import PostgreSQLPlugin
|
14
|
+
from .plugins.sqlite import SQLitePlugin
|
15
|
+
|
16
|
+
T = TypeVar('T', bound='ThothDbManager')
|
17
|
+
|
18
|
+
class ThothDbManager(ABC):
|
19
|
+
"""
|
20
|
+
This class provides methods for interacting with a database.
|
21
|
+
It follows a singleton pattern for each unique set of connection parameters.
|
22
|
+
|
23
|
+
This class now serves as a compatibility layer over the new plugin architecture.
|
24
|
+
"""
|
25
|
+
_instances: ClassVar[Dict[tuple, Any]] = {}
|
26
|
+
_lock: ClassVar[Lock] = Lock()
|
27
|
+
|
28
|
+
@classmethod
|
29
|
+
def get_instance(cls: Type[T], db_type: str, **kwargs) -> T:
|
30
|
+
"""
|
31
|
+
Get or create a singleton instance based on the database type.
|
32
|
+
This acts as a factory for different database manager implementations.
|
33
|
+
|
34
|
+
Now uses the new plugin architecture while maintaining backward compatibility.
|
35
|
+
|
36
|
+
Args:
|
37
|
+
db_type (str): The type of database (e.g., 'postgresql', 'sqlite', 'mysql').
|
38
|
+
**kwargs: Connection parameters specific to the database implementation.
|
39
|
+
|
40
|
+
Returns:
|
41
|
+
An instance of the appropriate database manager.
|
42
|
+
|
43
|
+
Raises:
|
44
|
+
ValueError: If the database type is unsupported or required parameters are missing.
|
45
|
+
"""
|
46
|
+
# Try new plugin architecture first
|
47
|
+
try:
|
48
|
+
if db_type in ["postgresql", "sqlite"]: # Currently supported by new architecture
|
49
|
+
# Extract required parameters
|
50
|
+
db_root_path = kwargs.get('db_root_path')
|
51
|
+
db_mode = kwargs.get('db_mode', 'dev')
|
52
|
+
|
53
|
+
if not db_root_path:
|
54
|
+
raise ValueError("db_root_path is required")
|
55
|
+
|
56
|
+
# Remove extracted parameters from kwargs to avoid duplicate parameter errors
|
57
|
+
kwargs_clean = kwargs.copy()
|
58
|
+
kwargs_clean.pop('db_root_path', None)
|
59
|
+
kwargs_clean.pop('db_mode', None)
|
60
|
+
|
61
|
+
# Create plugin instance using factory
|
62
|
+
plugin = ThothDbFactory.create_manager(db_type, db_root_path, db_mode, **kwargs_clean)
|
63
|
+
|
64
|
+
# Wrap plugin in compatibility adapter
|
65
|
+
return ThothDbManagerAdapter(plugin)
|
66
|
+
|
67
|
+
except Exception as e:
|
68
|
+
logging.warning(f"Failed to use new plugin architecture for {db_type}: {e}. Falling back to legacy implementation.")
|
69
|
+
|
70
|
+
# Use unified plugin system for all database types
|
71
|
+
try:
|
72
|
+
# Import all plugins to ensure they're registered
|
73
|
+
from . import plugins
|
74
|
+
|
75
|
+
# Create plugin instance using factory
|
76
|
+
plugin = ThothDbFactory.create_manager(db_type, **kwargs)
|
77
|
+
|
78
|
+
# Wrap plugin in compatibility adapter
|
79
|
+
return ThothDbManagerAdapter(plugin)
|
80
|
+
|
81
|
+
except Exception as e:
|
82
|
+
logging.error(f"Failed to create {db_type} manager: {e}")
|
83
|
+
raise ValueError(f"Unsupported database type '{db_type}' or invalid parameters: {e}")
|
84
|
+
|
85
|
+
def __init__(self, db_root_path: str, db_mode: str = "dev", db_type: Optional[str] = None, **kwargs) -> None:
|
86
|
+
"""
|
87
|
+
Initialize the database manager.
|
88
|
+
|
89
|
+
Args:
|
90
|
+
db_root_path (str): Path to the database root directory.
|
91
|
+
db_mode (str, optional): Database mode (dev, prod, etc.). Defaults to "dev".
|
92
|
+
db_type (Optional[str], optional): Type of database. Defaults to None.
|
93
|
+
**kwargs: Additional parameters specific to the database implementation.
|
94
|
+
"""
|
95
|
+
self._validate_common_params(db_root_path, db_mode)
|
96
|
+
|
97
|
+
self.db_root_path = db_root_path
|
98
|
+
self.db_mode = db_mode
|
99
|
+
self.db_type = db_type
|
100
|
+
|
101
|
+
# These will be set by subclasses
|
102
|
+
self.engine = None
|
103
|
+
self.db_id = None
|
104
|
+
self.db_directory_path = None
|
105
|
+
|
106
|
+
# LSH related attributes (for backward compatibility)
|
107
|
+
self.lsh = None
|
108
|
+
self.minhashes = None
|
109
|
+
self.vector_db = None
|
110
|
+
|
111
|
+
# New LSH manager (lazy initialization)
|
112
|
+
self._lsh_manager = None
|
113
|
+
|
114
|
+
# Flag to track initialization
|
115
|
+
self._initialized = False
|
116
|
+
|
117
|
+
def _validate_common_params(self, db_root_path: str, db_mode: str) -> None:
|
118
|
+
"""
|
119
|
+
Validate common parameters for all database implementations.
|
120
|
+
|
121
|
+
Args:
|
122
|
+
db_root_path (str): Path to the database root directory.
|
123
|
+
db_mode (str): Database mode (dev, prod, etc.).
|
124
|
+
|
125
|
+
Raises:
|
126
|
+
ValueError: If parameters are invalid.
|
127
|
+
"""
|
128
|
+
if not db_root_path:
|
129
|
+
raise ValueError("db_root_path is required")
|
130
|
+
|
131
|
+
if not isinstance(db_mode, str):
|
132
|
+
raise TypeError("db_mode must be a string")
|
133
|
+
|
134
|
+
def _setup_directory_path(self, db_id: str) -> None:
|
135
|
+
"""
|
136
|
+
Set up the database directory path.
|
137
|
+
|
138
|
+
Args:
|
139
|
+
db_id (str): Database identifier.
|
140
|
+
"""
|
141
|
+
if isinstance(self.db_root_path, str):
|
142
|
+
self.db_root_path = Path(self.db_root_path)
|
143
|
+
|
144
|
+
self.db_directory_path = self.db_root_path / f"{self.db_mode}_databases" / db_id
|
145
|
+
self.db_id = db_id
|
146
|
+
|
147
|
+
# Reset LSH manager when directory path changes
|
148
|
+
self._lsh_manager = None
|
149
|
+
|
150
|
+
@property
|
151
|
+
def lsh_manager(self) -> Optional[LshManager]:
|
152
|
+
"""
|
153
|
+
Lazy load LSH manager.
|
154
|
+
|
155
|
+
Returns:
|
156
|
+
LshManager instance if db_directory_path is set, None otherwise
|
157
|
+
"""
|
158
|
+
if self._lsh_manager is None and self.db_directory_path:
|
159
|
+
self._lsh_manager = LshManager(self.db_directory_path)
|
160
|
+
return self._lsh_manager
|
161
|
+
|
162
|
+
@abstractmethod
|
163
|
+
def execute_sql(self,
|
164
|
+
sql: str,
|
165
|
+
params: Optional[Dict] = None,
|
166
|
+
fetch: Union[str, int] = "all",
|
167
|
+
timeout: int = 60) -> Any:
|
168
|
+
"""
|
169
|
+
Abstract method to execute SQL queries.
|
170
|
+
|
171
|
+
Args:
|
172
|
+
sql (str): The SQL query to execute.
|
173
|
+
params (Optional[Dict]): Parameters for the SQL query.
|
174
|
+
fetch (Union[str, int]): Specifies how to fetch the results.
|
175
|
+
timeout (int): Timeout for the query execution.
|
176
|
+
|
177
|
+
Returns:
|
178
|
+
Any: The result of the SQL query execution.
|
179
|
+
"""
|
180
|
+
pass
|
181
|
+
|
182
|
+
@abstractmethod
|
183
|
+
def get_unique_values(self) -> Dict[str, Dict[str, List[str]]]:
|
184
|
+
"""
|
185
|
+
Get unique values from the database.
|
186
|
+
|
187
|
+
Returns:
|
188
|
+
Dict[str, Dict[str, List[str]]]: Dictionary where:
|
189
|
+
- outer key is table name
|
190
|
+
- inner key is column name
|
191
|
+
- value is list of unique values
|
192
|
+
"""
|
193
|
+
pass
|
194
|
+
|
195
|
+
@abstractmethod
|
196
|
+
def get_tables(self) -> List[Dict[str, str]]:
|
197
|
+
"""
|
198
|
+
Abstract method to get a list of tables in the database.
|
199
|
+
|
200
|
+
Returns:
|
201
|
+
List[Dict[str, str]]: A list of dictionaries, where each dictionary
|
202
|
+
represents a table with 'name' and 'comment' keys.
|
203
|
+
"""
|
204
|
+
pass
|
205
|
+
|
206
|
+
@abstractmethod
|
207
|
+
def get_columns(self, table_name: str) -> List[Dict[str, Any]]:
|
208
|
+
"""
|
209
|
+
Abstract method to get a list of columns for a given table.
|
210
|
+
|
211
|
+
Args:
|
212
|
+
table_name (str): The name of the table.
|
213
|
+
|
214
|
+
Returns:
|
215
|
+
List[Dict[str, Any]]: A list of dictionaries, where each dictionary
|
216
|
+
represents a column with 'name', 'data_type',
|
217
|
+
'comment', and 'is_pk' keys.
|
218
|
+
"""
|
219
|
+
pass
|
220
|
+
|
221
|
+
@abstractmethod
|
222
|
+
def get_foreign_keys(self) -> List[Dict[str, str]]:
|
223
|
+
"""
|
224
|
+
Abstract method to get a list of foreign key relationships in the database.
|
225
|
+
|
226
|
+
Returns:
|
227
|
+
List[Dict[str, str]]: A list of dictionaries, where each dictionary
|
228
|
+
represents a foreign key relationship with
|
229
|
+
'source_table_name', 'source_column_name',
|
230
|
+
'target_table_name', and 'target_column_name' keys.
|
231
|
+
"""
|
232
|
+
pass
|
233
|
+
|
234
|
+
@abstractmethod
|
235
|
+
def get_example_data(self, table_name: str, number_of_rows: int = 30) -> Dict[str, List[Any]]:
|
236
|
+
"""
|
237
|
+
Abstract method to get example data (most frequent values) for each column in a table.
|
238
|
+
|
239
|
+
Args:
|
240
|
+
table_name (str): The name of the table.
|
241
|
+
number_of_rows (int, optional): Maximum number of example values to return per column. Defaults to 30.
|
242
|
+
|
243
|
+
Returns:
|
244
|
+
Dict[str, List[Any]]: A dictionary mapping column names to lists of example values.
|
245
|
+
"""
|
246
|
+
pass
|
247
|
+
|
248
|
+
def set_lsh(self) -> str:
|
249
|
+
"""
|
250
|
+
Sets the LSH and minhashes attributes by loading from storage.
|
251
|
+
|
252
|
+
This method maintains backward compatibility while using the new LSH manager.
|
253
|
+
"""
|
254
|
+
with self._lock:
|
255
|
+
if self.lsh is None:
|
256
|
+
try:
|
257
|
+
# Use the new LSH manager
|
258
|
+
if self.lsh_manager and self.lsh_manager.load_lsh():
|
259
|
+
# Set backward compatibility attributes
|
260
|
+
self.lsh = self.lsh_manager.lsh
|
261
|
+
self.minhashes = self.lsh_manager.minhashes
|
262
|
+
return "success"
|
263
|
+
else:
|
264
|
+
# Fallback to old method for compatibility
|
265
|
+
lsh_path = self.db_directory_path / "preprocessed" / f"{self.db_id}_lsh.pkl"
|
266
|
+
minhashes_path = self.db_directory_path / "preprocessed" / f"{self.db_id}_minhashes.pkl"
|
267
|
+
|
268
|
+
if not lsh_path.exists() or not minhashes_path.exists():
|
269
|
+
raise FileNotFoundError(f"LSH or MinHashes file not found for {self.db_id}")
|
270
|
+
|
271
|
+
with lsh_path.open("rb") as file:
|
272
|
+
self.lsh = pickle.load(file)
|
273
|
+
with minhashes_path.open("rb") as file:
|
274
|
+
self.minhashes = pickle.load(file)
|
275
|
+
return "success"
|
276
|
+
except Exception as e:
|
277
|
+
logging.error(f"Error loading LSH: {str(e)}")
|
278
|
+
self.lsh = "error"
|
279
|
+
self.minhashes = "error"
|
280
|
+
return "error"
|
281
|
+
elif self.lsh == "error":
|
282
|
+
return "error"
|
283
|
+
else:
|
284
|
+
return "success"
|
285
|
+
|
286
|
+
def query_lsh(self,
|
287
|
+
keyword: str,
|
288
|
+
signature_size: int = 30,
|
289
|
+
n_gram: int = 3,
|
290
|
+
top_n: int = 10) -> Dict[str, Dict[str, List[str]]]:
|
291
|
+
"""
|
292
|
+
Queries the LSH for similar values to the given keyword.
|
293
|
+
|
294
|
+
Args:
|
295
|
+
keyword (str): The keyword to search for.
|
296
|
+
signature_size (int, optional): The size of the MinHash signature. Defaults to 30.
|
297
|
+
n_gram (int, optional): The n-gram size for the MinHash. Defaults to 3.
|
298
|
+
top_n (int, optional): The number of top results to return. Defaults to 10.
|
299
|
+
|
300
|
+
Returns:
|
301
|
+
Dict[str, Dict[str, List[str]]]: Dictionary where:
|
302
|
+
- outer key is table name
|
303
|
+
- inner key is column name
|
304
|
+
- value is list of similar strings
|
305
|
+
"""
|
306
|
+
# Try using the new LSH manager first
|
307
|
+
if self.lsh_manager:
|
308
|
+
try:
|
309
|
+
return self.lsh_manager.query(
|
310
|
+
keyword=keyword,
|
311
|
+
signature_size=signature_size,
|
312
|
+
n_gram=n_gram,
|
313
|
+
top_n=top_n
|
314
|
+
)
|
315
|
+
except Exception as e:
|
316
|
+
logging.warning(f"LSH manager query failed, falling back to old method: {e}")
|
317
|
+
|
318
|
+
# Fallback to old method for backward compatibility
|
319
|
+
lsh_status = self.set_lsh()
|
320
|
+
if lsh_status == "success":
|
321
|
+
# Import here to avoid circular imports
|
322
|
+
from .helpers.search import _query_lsh
|
323
|
+
return _query_lsh(self.lsh, self.minhashes, keyword, signature_size, n_gram, top_n)
|
324
|
+
else:
|
325
|
+
raise Exception(f"Error loading LSH for {self.db_id}")
|
326
|
+
|
327
|
+
|
328
|
+
class ThothDbManagerAdapter(ThothDbManager):
|
329
|
+
"""
|
330
|
+
Adapter class that wraps the new plugin architecture to provide backward compatibility
|
331
|
+
with the original ThothDbManager interface.
|
332
|
+
"""
|
333
|
+
|
334
|
+
def __init__(self, plugin: DbPlugin):
|
335
|
+
"""
|
336
|
+
Initialize the adapter with a plugin instance.
|
337
|
+
|
338
|
+
Args:
|
339
|
+
plugin: Database plugin instance
|
340
|
+
"""
|
341
|
+
self.plugin = plugin
|
342
|
+
|
343
|
+
# Copy plugin attributes for backward compatibility
|
344
|
+
self.db_root_path = plugin.db_root_path
|
345
|
+
self.db_mode = plugin.db_mode
|
346
|
+
self.db_type = plugin.supported_db_types[0] if plugin.supported_db_types else "unknown"
|
347
|
+
self.db_id = getattr(plugin, 'db_id', None)
|
348
|
+
self.db_directory_path = getattr(plugin, 'db_directory_path', None)
|
349
|
+
|
350
|
+
# Engine and connection (delegated to adapter)
|
351
|
+
self.engine = getattr(plugin.adapter, 'engine', None) if plugin.adapter else None
|
352
|
+
|
353
|
+
# LSH related attributes (for backward compatibility)
|
354
|
+
self.lsh = None
|
355
|
+
self.minhashes = None
|
356
|
+
self.vector_db = None
|
357
|
+
|
358
|
+
# Flag to track initialization
|
359
|
+
self._initialized = plugin._initialized
|
360
|
+
|
361
|
+
@property
|
362
|
+
def lsh_manager(self):
|
363
|
+
"""Access LSH manager through plugin"""
|
364
|
+
return getattr(self.plugin, 'lsh_manager', None)
|
365
|
+
|
366
|
+
def execute_sql(self, sql: str, params: Optional[Dict] = None, fetch: Union[str, int] = "all", timeout: int = 60) -> Any:
|
367
|
+
"""Execute SQL queries through plugin"""
|
368
|
+
return self.plugin.execute_sql(sql, params, fetch, timeout)
|
369
|
+
|
370
|
+
def get_unique_values(self) -> Dict[str, Dict[str, List[str]]]:
|
371
|
+
"""Get unique values through plugin"""
|
372
|
+
return self.plugin.get_unique_values()
|
373
|
+
|
374
|
+
def get_tables(self) -> List[Dict[str, str]]:
|
375
|
+
"""Get tables through plugin"""
|
376
|
+
return self.plugin.get_tables()
|
377
|
+
|
378
|
+
def get_columns(self, table_name: str) -> List[Dict[str, Any]]:
|
379
|
+
"""Get columns through plugin"""
|
380
|
+
return self.plugin.get_columns(table_name)
|
381
|
+
|
382
|
+
def get_foreign_keys(self) -> List[Dict[str, str]]:
|
383
|
+
"""Get foreign keys through plugin"""
|
384
|
+
return self.plugin.get_foreign_keys()
|
385
|
+
|
386
|
+
def set_lsh(self) -> str:
|
387
|
+
"""Set LSH through plugin"""
|
388
|
+
if hasattr(self.plugin, 'set_lsh'):
|
389
|
+
result = self.plugin.set_lsh()
|
390
|
+
|
391
|
+
# Update backward compatibility attributes
|
392
|
+
if result == "success" and self.lsh_manager:
|
393
|
+
self.lsh = getattr(self.lsh_manager, 'lsh', None)
|
394
|
+
self.minhashes = getattr(self.lsh_manager, 'minhashes', None)
|
395
|
+
|
396
|
+
return result
|
397
|
+
else:
|
398
|
+
# Fallback to original implementation
|
399
|
+
return super().set_lsh()
|
400
|
+
|
401
|
+
def query_lsh(self, keyword: str, signature_size: int = 30, n_gram: int = 3, top_n: int = 10) -> Dict[str, Dict[str, List[str]]]:
|
402
|
+
"""Query LSH through plugin"""
|
403
|
+
if hasattr(self.plugin, 'query_lsh'):
|
404
|
+
return self.plugin.query_lsh(keyword, signature_size, n_gram, top_n)
|
405
|
+
else:
|
406
|
+
# Fallback to original implementation
|
407
|
+
return super().query_lsh(keyword, signature_size, n_gram, top_n)
|
408
|
+
|
409
|
+
# Document-based methods (new functionality)
|
410
|
+
def get_tables_as_documents(self):
|
411
|
+
"""Get tables as document objects"""
|
412
|
+
if self.plugin.adapter:
|
413
|
+
return self.plugin.adapter.get_tables_as_documents()
|
414
|
+
return []
|
415
|
+
|
416
|
+
def get_columns_as_documents(self, table_name: str):
|
417
|
+
"""Get columns as document objects"""
|
418
|
+
if self.plugin.adapter:
|
419
|
+
return self.plugin.adapter.get_columns_as_documents(table_name)
|
420
|
+
return []
|
421
|
+
|
422
|
+
def get_foreign_keys_as_documents(self):
|
423
|
+
"""Get foreign keys as document objects"""
|
424
|
+
if self.plugin.adapter:
|
425
|
+
return self.plugin.adapter.get_foreign_keys_as_documents()
|
426
|
+
return []
|
427
|
+
|
428
|
+
def get_schemas_as_documents(self):
|
429
|
+
"""Get schemas as document objects"""
|
430
|
+
if self.plugin.adapter:
|
431
|
+
return self.plugin.adapter.get_schemas_as_documents()
|
432
|
+
return []
|
433
|
+
|
434
|
+
def get_indexes_as_documents(self, table_name: Optional[str] = None):
|
435
|
+
"""Get indexes as document objects"""
|
436
|
+
if self.plugin.adapter:
|
437
|
+
return self.plugin.adapter.get_indexes_as_documents(table_name)
|
438
|
+
return []
|
439
|
+
|
440
|
+
def get_connection_info(self) -> Dict[str, Any]:
|
441
|
+
"""Get connection information"""
|
442
|
+
if hasattr(self.plugin, 'get_connection_info'):
|
443
|
+
return self.plugin.get_connection_info()
|
444
|
+
return {}
|
445
|
+
|
446
|
+
def health_check(self) -> bool:
|
447
|
+
"""Check database health"""
|
448
|
+
if self.plugin.adapter:
|
449
|
+
return self.plugin.adapter.health_check()
|
450
|
+
return False
|
451
|
+
|
452
|
+
def get_example_data(self, table_name: str, number_of_rows: int = 30) -> Dict[str, List[Any]]:
|
453
|
+
"""Get example data through plugin"""
|
454
|
+
if hasattr(self.plugin, 'get_example_data'):
|
455
|
+
return self.plugin.get_example_data(table_name, number_of_rows)
|
456
|
+
elif self.plugin.adapter:
|
457
|
+
return self.plugin.adapter.get_example_data(table_name, number_of_rows)
|
458
|
+
else:
|
459
|
+
raise RuntimeError("Plugin not initialized or doesn't support get_example_data")
|
@@ -0,0 +1,136 @@
|
|
1
|
+
"""
|
2
|
+
Thoth Database Manager - A unified interface for multiple database systems.
|
3
|
+
|
4
|
+
This package provides database-agnostic operations, LSH similarity search,
|
5
|
+
and an extensible plugin architecture for managing SQL databases.
|
6
|
+
"""
|
7
|
+
|
8
|
+
# Core classes - always available
|
9
|
+
from .ThothDbManager import ThothDbManager
|
10
|
+
from .core.factory import ThothDbFactory
|
11
|
+
from .core.interfaces import DbPlugin, DbAdapter
|
12
|
+
from .core.registry import DbPluginRegistry
|
13
|
+
|
14
|
+
# Document models
|
15
|
+
from .documents import (
|
16
|
+
BaseThothDbDocument,
|
17
|
+
TableDocument,
|
18
|
+
ColumnDocument,
|
19
|
+
QueryDocument,
|
20
|
+
SchemaDocument,
|
21
|
+
ForeignKeyDocument,
|
22
|
+
IndexDocument,
|
23
|
+
ThothDbType,
|
24
|
+
create_document
|
25
|
+
)
|
26
|
+
|
27
|
+
# Export LSH functionality for backward compatibility
|
28
|
+
from .lsh.factory import make_db_lsh
|
29
|
+
from .lsh import LshManager, LshFactory
|
30
|
+
|
31
|
+
# Dynamic import system
|
32
|
+
from .dynamic_imports import (
|
33
|
+
import_manager,
|
34
|
+
import_adapter,
|
35
|
+
import_plugin,
|
36
|
+
get_available_databases,
|
37
|
+
import_database_components,
|
38
|
+
DatabaseImportError,
|
39
|
+
# Convenience functions
|
40
|
+
import_postgresql,
|
41
|
+
import_mysql,
|
42
|
+
import_sqlite,
|
43
|
+
import_sqlserver,
|
44
|
+
import_oracle,
|
45
|
+
import_mariadb,
|
46
|
+
import_informix,
|
47
|
+
import_supabase,
|
48
|
+
)
|
49
|
+
|
50
|
+
# Legacy API - will be dynamically imported when accessed
|
51
|
+
def __getattr__(name: str):
|
52
|
+
"""Dynamic attribute access for database managers."""
|
53
|
+
if name == 'ThothPgManager':
|
54
|
+
return import_manager('postgresql')
|
55
|
+
elif name == 'ThothSqliteManager':
|
56
|
+
return import_manager('sqlite')
|
57
|
+
elif name == 'ThothMySqlManager':
|
58
|
+
return import_manager('mysql')
|
59
|
+
elif name == 'ThothMariaDbManager':
|
60
|
+
return import_manager('mariadb')
|
61
|
+
elif name == 'ThothSqlServerManager':
|
62
|
+
return import_manager('sqlserver')
|
63
|
+
elif name == 'ThothOracleManager':
|
64
|
+
return import_manager('oracle')
|
65
|
+
elif name == 'ThothInformixManager':
|
66
|
+
return import_manager('informix')
|
67
|
+
elif name == 'ThothSupabaseManager':
|
68
|
+
return import_manager('supabase')
|
69
|
+
|
70
|
+
raise AttributeError(f"module 'thoth_dbmanager' has no attribute '{name}'")
|
71
|
+
|
72
|
+
# Public API
|
73
|
+
__all__ = [
|
74
|
+
# Legacy API
|
75
|
+
"ThothDbManager",
|
76
|
+
"ThothPgManager",
|
77
|
+
"ThothSqliteManager",
|
78
|
+
"ThothMySqlManager",
|
79
|
+
"ThothMariaDbManager",
|
80
|
+
"ThothSqlServerManager",
|
81
|
+
"ThothOracleManager",
|
82
|
+
"ThothInformixManager",
|
83
|
+
"ThothSupabaseManager",
|
84
|
+
|
85
|
+
# New architecture
|
86
|
+
"ThothDbFactory",
|
87
|
+
"DbPluginRegistry",
|
88
|
+
"DbPlugin",
|
89
|
+
"DbAdapter",
|
90
|
+
|
91
|
+
# Document models
|
92
|
+
"BaseThothDbDocument",
|
93
|
+
"TableDocument",
|
94
|
+
"ColumnDocument",
|
95
|
+
"QueryDocument",
|
96
|
+
"SchemaDocument",
|
97
|
+
"ForeignKeyDocument",
|
98
|
+
"IndexDocument",
|
99
|
+
"ThothDbType",
|
100
|
+
"create_document",
|
101
|
+
|
102
|
+
# Plugins
|
103
|
+
"PostgreSQLPlugin",
|
104
|
+
"SQLitePlugin",
|
105
|
+
"MySQLPlugin",
|
106
|
+
"MariaDBPlugin",
|
107
|
+
"SQLServerPlugin",
|
108
|
+
"OraclePlugin",
|
109
|
+
"InformixPlugin",
|
110
|
+
"SupabasePlugin",
|
111
|
+
|
112
|
+
# Adapters
|
113
|
+
"PostgreSQLAdapter",
|
114
|
+
"SQLiteAdapter",
|
115
|
+
"MySQLAdapter",
|
116
|
+
"MariaDBAdapter",
|
117
|
+
"SQLServerAdapter",
|
118
|
+
"OracleAdapter",
|
119
|
+
"InformixAdapter",
|
120
|
+
"SupabaseAdapter",
|
121
|
+
|
122
|
+
# LSH functionality
|
123
|
+
"make_db_lsh",
|
124
|
+
"LshManager",
|
125
|
+
"LshFactory",
|
126
|
+
|
127
|
+
# Dynamic import system
|
128
|
+
"import_manager",
|
129
|
+
"import_adapter",
|
130
|
+
"import_plugin",
|
131
|
+
"get_available_databases",
|
132
|
+
"import_database_components",
|
133
|
+
"DatabaseImportError",
|
134
|
+
]
|
135
|
+
|
136
|
+
__version__ = "0.4.0"
|
@@ -0,0 +1,21 @@
|
|
1
|
+
"""
|
2
|
+
Database adapters for Thoth SQL Database Manager.
|
3
|
+
"""
|
4
|
+
|
5
|
+
from .postgresql import PostgreSQLAdapter
|
6
|
+
from .sqlite import SQLiteAdapter
|
7
|
+
from .supabase import SupabaseAdapter
|
8
|
+
from .mysql import MySQLAdapter
|
9
|
+
from .mariadb import MariaDBAdapter
|
10
|
+
from .sqlserver import SQLServerAdapter
|
11
|
+
from .oracle import OracleAdapter
|
12
|
+
|
13
|
+
__all__ = [
|
14
|
+
"PostgreSQLAdapter",
|
15
|
+
"SQLiteAdapter",
|
16
|
+
"SupabaseAdapter",
|
17
|
+
"MySQLAdapter",
|
18
|
+
"MariaDBAdapter",
|
19
|
+
"SQLServerAdapter",
|
20
|
+
"OracleAdapter",
|
21
|
+
]
|