MindsDB 25.9.2.0a1__py3-none-any.whl → 25.10.0rc1__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.
Potentially problematic release.
This version of MindsDB might be problematic. Click here for more details.
- mindsdb/__about__.py +1 -1
- mindsdb/__main__.py +40 -29
- mindsdb/api/a2a/__init__.py +1 -1
- mindsdb/api/a2a/agent.py +16 -10
- mindsdb/api/a2a/common/server/server.py +7 -3
- mindsdb/api/a2a/common/server/task_manager.py +12 -5
- mindsdb/api/a2a/common/types.py +66 -0
- mindsdb/api/a2a/task_manager.py +65 -17
- mindsdb/api/common/middleware.py +10 -12
- mindsdb/api/executor/command_executor.py +51 -40
- mindsdb/api/executor/datahub/datanodes/datanode.py +2 -2
- mindsdb/api/executor/datahub/datanodes/information_schema_datanode.py +7 -13
- mindsdb/api/executor/datahub/datanodes/integration_datanode.py +101 -49
- mindsdb/api/executor/datahub/datanodes/project_datanode.py +8 -4
- mindsdb/api/executor/datahub/datanodes/system_tables.py +3 -2
- mindsdb/api/executor/exceptions.py +29 -10
- mindsdb/api/executor/planner/plan_join.py +17 -3
- mindsdb/api/executor/planner/query_prepare.py +2 -20
- mindsdb/api/executor/sql_query/sql_query.py +74 -74
- mindsdb/api/executor/sql_query/steps/fetch_dataframe.py +1 -2
- mindsdb/api/executor/sql_query/steps/subselect_step.py +0 -1
- mindsdb/api/executor/utilities/functions.py +6 -6
- mindsdb/api/executor/utilities/sql.py +37 -20
- mindsdb/api/http/gui.py +5 -11
- mindsdb/api/http/initialize.py +75 -61
- mindsdb/api/http/namespaces/agents.py +10 -15
- mindsdb/api/http/namespaces/analysis.py +13 -20
- mindsdb/api/http/namespaces/auth.py +1 -1
- mindsdb/api/http/namespaces/chatbots.py +0 -5
- mindsdb/api/http/namespaces/config.py +15 -11
- mindsdb/api/http/namespaces/databases.py +140 -201
- mindsdb/api/http/namespaces/file.py +17 -4
- mindsdb/api/http/namespaces/handlers.py +17 -7
- mindsdb/api/http/namespaces/knowledge_bases.py +28 -7
- mindsdb/api/http/namespaces/models.py +94 -126
- mindsdb/api/http/namespaces/projects.py +13 -22
- mindsdb/api/http/namespaces/sql.py +33 -25
- mindsdb/api/http/namespaces/tab.py +27 -37
- mindsdb/api/http/namespaces/views.py +1 -1
- mindsdb/api/http/start.py +16 -10
- mindsdb/api/mcp/__init__.py +2 -1
- mindsdb/api/mysql/mysql_proxy/executor/mysql_executor.py +15 -20
- mindsdb/api/mysql/mysql_proxy/mysql_proxy.py +26 -50
- mindsdb/api/mysql/mysql_proxy/utilities/__init__.py +0 -1
- mindsdb/api/mysql/mysql_proxy/utilities/dump.py +8 -2
- mindsdb/integrations/handlers/byom_handler/byom_handler.py +165 -190
- mindsdb/integrations/handlers/databricks_handler/databricks_handler.py +98 -46
- mindsdb/integrations/handlers/druid_handler/druid_handler.py +32 -40
- mindsdb/integrations/handlers/file_handler/file_handler.py +7 -0
- mindsdb/integrations/handlers/gitlab_handler/gitlab_handler.py +5 -2
- mindsdb/integrations/handlers/lightwood_handler/functions.py +45 -79
- mindsdb/integrations/handlers/mssql_handler/mssql_handler.py +438 -100
- mindsdb/integrations/handlers/mssql_handler/requirements_odbc.txt +3 -0
- mindsdb/integrations/handlers/mysql_handler/mysql_handler.py +235 -3
- mindsdb/integrations/handlers/oracle_handler/__init__.py +2 -0
- mindsdb/integrations/handlers/oracle_handler/connection_args.py +7 -1
- mindsdb/integrations/handlers/oracle_handler/oracle_handler.py +321 -16
- mindsdb/integrations/handlers/oracle_handler/requirements.txt +1 -1
- mindsdb/integrations/handlers/postgres_handler/postgres_handler.py +14 -2
- mindsdb/integrations/handlers/shopify_handler/shopify_handler.py +25 -12
- mindsdb/integrations/handlers/snowflake_handler/snowflake_handler.py +2 -1
- mindsdb/integrations/handlers/statsforecast_handler/requirements.txt +1 -0
- mindsdb/integrations/handlers/statsforecast_handler/requirements_extra.txt +1 -0
- mindsdb/integrations/handlers/web_handler/urlcrawl_helpers.py +4 -4
- mindsdb/integrations/handlers/zendesk_handler/zendesk_tables.py +144 -111
- mindsdb/integrations/libs/api_handler.py +10 -10
- mindsdb/integrations/libs/base.py +4 -4
- mindsdb/integrations/libs/llm/utils.py +2 -2
- mindsdb/integrations/libs/ml_handler_process/create_engine_process.py +4 -7
- mindsdb/integrations/libs/ml_handler_process/func_call_process.py +2 -7
- mindsdb/integrations/libs/ml_handler_process/learn_process.py +37 -47
- mindsdb/integrations/libs/ml_handler_process/update_engine_process.py +4 -7
- mindsdb/integrations/libs/ml_handler_process/update_process.py +2 -7
- mindsdb/integrations/libs/process_cache.py +132 -140
- mindsdb/integrations/libs/response.py +18 -12
- mindsdb/integrations/libs/vectordatabase_handler.py +26 -0
- mindsdb/integrations/utilities/files/file_reader.py +6 -7
- mindsdb/integrations/utilities/handlers/auth_utilities/snowflake/__init__.py +1 -0
- mindsdb/integrations/utilities/handlers/auth_utilities/snowflake/snowflake_jwt_gen.py +151 -0
- mindsdb/integrations/utilities/rag/config_loader.py +37 -26
- mindsdb/integrations/utilities/rag/rerankers/base_reranker.py +83 -30
- mindsdb/integrations/utilities/rag/rerankers/reranker_compressor.py +4 -4
- mindsdb/integrations/utilities/rag/retrievers/sql_retriever.py +55 -133
- mindsdb/integrations/utilities/rag/settings.py +58 -133
- mindsdb/integrations/utilities/rag/splitters/file_splitter.py +5 -15
- mindsdb/interfaces/agents/agents_controller.py +2 -3
- mindsdb/interfaces/agents/constants.py +0 -2
- mindsdb/interfaces/agents/litellm_server.py +34 -58
- mindsdb/interfaces/agents/mcp_client_agent.py +10 -10
- mindsdb/interfaces/agents/mindsdb_database_agent.py +5 -5
- mindsdb/interfaces/agents/run_mcp_agent.py +12 -21
- mindsdb/interfaces/chatbot/chatbot_task.py +20 -23
- mindsdb/interfaces/chatbot/polling.py +30 -18
- mindsdb/interfaces/data_catalog/data_catalog_loader.py +16 -17
- mindsdb/interfaces/data_catalog/data_catalog_reader.py +15 -4
- mindsdb/interfaces/database/data_handlers_cache.py +190 -0
- mindsdb/interfaces/database/database.py +3 -3
- mindsdb/interfaces/database/integrations.py +7 -110
- mindsdb/interfaces/database/projects.py +2 -6
- mindsdb/interfaces/database/views.py +1 -4
- mindsdb/interfaces/file/file_controller.py +6 -6
- mindsdb/interfaces/functions/controller.py +1 -1
- mindsdb/interfaces/functions/to_markdown.py +2 -2
- mindsdb/interfaces/jobs/jobs_controller.py +5 -9
- mindsdb/interfaces/jobs/scheduler.py +3 -9
- mindsdb/interfaces/knowledge_base/controller.py +244 -128
- mindsdb/interfaces/knowledge_base/evaluate.py +36 -41
- mindsdb/interfaces/knowledge_base/executor.py +11 -0
- mindsdb/interfaces/knowledge_base/llm_client.py +51 -17
- mindsdb/interfaces/knowledge_base/preprocessing/json_chunker.py +40 -61
- mindsdb/interfaces/model/model_controller.py +172 -168
- mindsdb/interfaces/query_context/context_controller.py +14 -2
- mindsdb/interfaces/skills/custom/text2sql/mindsdb_sql_toolkit.py +10 -14
- mindsdb/interfaces/skills/retrieval_tool.py +43 -50
- mindsdb/interfaces/skills/skill_tool.py +2 -2
- mindsdb/interfaces/skills/skills_controller.py +1 -4
- mindsdb/interfaces/skills/sql_agent.py +25 -19
- mindsdb/interfaces/storage/db.py +16 -6
- mindsdb/interfaces/storage/fs.py +114 -169
- mindsdb/interfaces/storage/json.py +19 -18
- mindsdb/interfaces/tabs/tabs_controller.py +49 -72
- mindsdb/interfaces/tasks/task_monitor.py +3 -9
- mindsdb/interfaces/tasks/task_thread.py +7 -9
- mindsdb/interfaces/triggers/trigger_task.py +7 -13
- mindsdb/interfaces/triggers/triggers_controller.py +47 -52
- mindsdb/migrations/migrate.py +16 -16
- mindsdb/utilities/api_status.py +58 -0
- mindsdb/utilities/config.py +68 -2
- mindsdb/utilities/exception.py +40 -1
- mindsdb/utilities/fs.py +0 -1
- mindsdb/utilities/hooks/profiling.py +17 -14
- mindsdb/utilities/json_encoder.py +24 -10
- mindsdb/utilities/langfuse.py +40 -45
- mindsdb/utilities/log.py +272 -0
- mindsdb/utilities/ml_task_queue/consumer.py +52 -58
- mindsdb/utilities/ml_task_queue/producer.py +26 -30
- mindsdb/utilities/render/sqlalchemy_render.py +22 -20
- mindsdb/utilities/starters.py +0 -10
- mindsdb/utilities/utils.py +2 -2
- {mindsdb-25.9.2.0a1.dist-info → mindsdb-25.10.0rc1.dist-info}/METADATA +293 -276
- {mindsdb-25.9.2.0a1.dist-info → mindsdb-25.10.0rc1.dist-info}/RECORD +144 -158
- mindsdb/api/mysql/mysql_proxy/utilities/exceptions.py +0 -14
- mindsdb/api/postgres/__init__.py +0 -0
- mindsdb/api/postgres/postgres_proxy/__init__.py +0 -0
- mindsdb/api/postgres/postgres_proxy/executor/__init__.py +0 -1
- mindsdb/api/postgres/postgres_proxy/executor/executor.py +0 -189
- mindsdb/api/postgres/postgres_proxy/postgres_packets/__init__.py +0 -0
- mindsdb/api/postgres/postgres_proxy/postgres_packets/errors.py +0 -322
- mindsdb/api/postgres/postgres_proxy/postgres_packets/postgres_fields.py +0 -34
- mindsdb/api/postgres/postgres_proxy/postgres_packets/postgres_message.py +0 -31
- mindsdb/api/postgres/postgres_proxy/postgres_packets/postgres_message_formats.py +0 -1265
- mindsdb/api/postgres/postgres_proxy/postgres_packets/postgres_message_identifiers.py +0 -31
- mindsdb/api/postgres/postgres_proxy/postgres_packets/postgres_packets.py +0 -253
- mindsdb/api/postgres/postgres_proxy/postgres_proxy.py +0 -477
- mindsdb/api/postgres/postgres_proxy/utilities/__init__.py +0 -10
- mindsdb/api/postgres/start.py +0 -11
- mindsdb/integrations/handlers/mssql_handler/tests/__init__.py +0 -0
- mindsdb/integrations/handlers/mssql_handler/tests/test_mssql_handler.py +0 -169
- mindsdb/integrations/handlers/oracle_handler/tests/__init__.py +0 -0
- mindsdb/integrations/handlers/oracle_handler/tests/test_oracle_handler.py +0 -32
- {mindsdb-25.9.2.0a1.dist-info → mindsdb-25.10.0rc1.dist-info}/WHEEL +0 -0
- {mindsdb-25.9.2.0a1.dist-info → mindsdb-25.10.0rc1.dist-info}/licenses/LICENSE +0 -0
- {mindsdb-25.9.2.0a1.dist-info → mindsdb-25.10.0rc1.dist-info}/top_level.txt +0 -0
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
1
3
|
import pandas as pd
|
|
2
4
|
import mysql.connector
|
|
3
5
|
|
|
@@ -6,7 +8,7 @@ from mindsdb.utilities.render.sqlalchemy_render import SqlalchemyRender
|
|
|
6
8
|
from mindsdb_sql_parser.ast.base import ASTNode
|
|
7
9
|
|
|
8
10
|
from mindsdb.utilities import log
|
|
9
|
-
from mindsdb.integrations.libs.base import
|
|
11
|
+
from mindsdb.integrations.libs.base import MetaDatabaseHandler
|
|
10
12
|
from mindsdb.integrations.libs.response import (
|
|
11
13
|
HandlerStatusResponse as StatusResponse,
|
|
12
14
|
HandlerResponse as Response,
|
|
@@ -104,7 +106,7 @@ def _make_table_response(result: list[dict], cursor: mysql.connector.cursor.MySQ
|
|
|
104
106
|
return response
|
|
105
107
|
|
|
106
108
|
|
|
107
|
-
class MySQLHandler(
|
|
109
|
+
class MySQLHandler(MetaDatabaseHandler):
|
|
108
110
|
"""
|
|
109
111
|
This handler handles connection and execution of the MySQL statements.
|
|
110
112
|
"""
|
|
@@ -237,7 +239,6 @@ class MySQLHandler(DatabaseHandler):
|
|
|
237
239
|
Returns:
|
|
238
240
|
Response: A response object containing the result of the query or an error message.
|
|
239
241
|
"""
|
|
240
|
-
|
|
241
242
|
need_to_close = not self.is_connected
|
|
242
243
|
connection = None
|
|
243
244
|
try:
|
|
@@ -314,3 +315,234 @@ class MySQLHandler(DatabaseHandler):
|
|
|
314
315
|
result = self.native_query(q)
|
|
315
316
|
result.to_columns_table_response(map_type_fn=_map_type)
|
|
316
317
|
return result
|
|
318
|
+
|
|
319
|
+
def meta_get_tables(self, table_names: Optional[list[str]] = None) -> Response:
|
|
320
|
+
"""
|
|
321
|
+
Retrieves metadata information about the tables in the MySQL database
|
|
322
|
+
to be stored in the data catalog.
|
|
323
|
+
|
|
324
|
+
Args:
|
|
325
|
+
table_names (list): A list of table names for which to retrieve metadata information.
|
|
326
|
+
|
|
327
|
+
Returns:
|
|
328
|
+
Response: A response object containing the metadata information.
|
|
329
|
+
"""
|
|
330
|
+
query = """
|
|
331
|
+
SELECT
|
|
332
|
+
t.TABLE_NAME as table_name,
|
|
333
|
+
t.TABLE_SCHEMA as table_schema,
|
|
334
|
+
t.TABLE_TYPE as table_type,
|
|
335
|
+
t.TABLE_COMMENT as table_description,
|
|
336
|
+
t.TABLE_ROWS as row_count
|
|
337
|
+
FROM information_schema.TABLES t
|
|
338
|
+
WHERE t.TABLE_SCHEMA = DATABASE()
|
|
339
|
+
AND t.TABLE_TYPE IN ('BASE TABLE', 'VIEW')
|
|
340
|
+
"""
|
|
341
|
+
|
|
342
|
+
if table_names is not None and len(table_names) > 0:
|
|
343
|
+
quoted_names = [f"'{t}'" for t in table_names]
|
|
344
|
+
query += f" AND t.TABLE_NAME IN ({','.join(quoted_names)})"
|
|
345
|
+
|
|
346
|
+
query += " ORDER BY t.TABLE_NAME"
|
|
347
|
+
|
|
348
|
+
result = self.native_query(query)
|
|
349
|
+
return result
|
|
350
|
+
|
|
351
|
+
def meta_get_columns(self, table_names: Optional[list[str]] = None) -> Response:
|
|
352
|
+
"""
|
|
353
|
+
Retrieves column metadata for the specified tables (or all tables if no list is provided).
|
|
354
|
+
|
|
355
|
+
Args:
|
|
356
|
+
table_names (list): A list of table names for which to retrieve column metadata.
|
|
357
|
+
|
|
358
|
+
Returns:
|
|
359
|
+
Response: A response object containing the column metadata.
|
|
360
|
+
"""
|
|
361
|
+
query = """
|
|
362
|
+
SELECT
|
|
363
|
+
c.TABLE_NAME as table_name,
|
|
364
|
+
c.COLUMN_NAME as column_name,
|
|
365
|
+
c.DATA_TYPE as data_type,
|
|
366
|
+
c.COLUMN_COMMENT as column_description,
|
|
367
|
+
c.COLUMN_DEFAULT as column_default,
|
|
368
|
+
CASE WHEN c.IS_NULLABLE = 'YES' THEN 1 ELSE 0 END as is_nullable
|
|
369
|
+
FROM information_schema.COLUMNS c
|
|
370
|
+
WHERE c.TABLE_SCHEMA = DATABASE()
|
|
371
|
+
"""
|
|
372
|
+
|
|
373
|
+
if table_names is not None and len(table_names) > 0:
|
|
374
|
+
quoted_names = [f"'{t}'" for t in table_names]
|
|
375
|
+
query += f" AND c.TABLE_NAME IN ({','.join(quoted_names)})"
|
|
376
|
+
|
|
377
|
+
query += " ORDER BY c.TABLE_NAME, c.ORDINAL_POSITION"
|
|
378
|
+
|
|
379
|
+
result = self.native_query(query)
|
|
380
|
+
return result
|
|
381
|
+
|
|
382
|
+
def meta_get_column_statistics(self, table_names: Optional[list[str]] = None) -> Response:
|
|
383
|
+
"""
|
|
384
|
+
Retrieves column statistics for the specified tables (or all tables if no list is provided).
|
|
385
|
+
Uses MySQL 8.0+ metadata sources (INFORMATION_SCHEMA.COLUMN_STATISTICS and INFORMATION_SCHEMA.STATISTICS) not requiring table scans.
|
|
386
|
+
|
|
387
|
+
Args:
|
|
388
|
+
table_names (list): A list of table names for which to retrieve column statistics.
|
|
389
|
+
|
|
390
|
+
Returns:
|
|
391
|
+
Response: A response object containing the column statistics.
|
|
392
|
+
"""
|
|
393
|
+
table_filter = ""
|
|
394
|
+
if table_names:
|
|
395
|
+
quoted = ",".join(f"'{t}'" for t in table_names)
|
|
396
|
+
table_filter = f" AND c.TABLE_NAME IN ({quoted})"
|
|
397
|
+
|
|
398
|
+
query = f"""
|
|
399
|
+
WITH cols AS (
|
|
400
|
+
SELECT c.TABLE_SCHEMA, c.TABLE_NAME, c.COLUMN_NAME, c.ORDINAL_POSITION
|
|
401
|
+
FROM information_schema.COLUMNS c
|
|
402
|
+
WHERE c.TABLE_SCHEMA = DATABASE()
|
|
403
|
+
{table_filter}
|
|
404
|
+
),
|
|
405
|
+
hist AS (
|
|
406
|
+
SELECT
|
|
407
|
+
cs.SCHEMA_NAME AS TABLE_SCHEMA,
|
|
408
|
+
cs.TABLE_NAME,
|
|
409
|
+
cs.COLUMN_NAME,
|
|
410
|
+
cs.HISTOGRAM,
|
|
411
|
+
JSON_LENGTH(cs.HISTOGRAM, '$.buckets') AS buckets_len
|
|
412
|
+
FROM information_schema.COLUMN_STATISTICS cs
|
|
413
|
+
WHERE cs.SCHEMA_NAME = DATABASE()
|
|
414
|
+
),
|
|
415
|
+
ndv AS (
|
|
416
|
+
SELECT
|
|
417
|
+
s.TABLE_SCHEMA,
|
|
418
|
+
s.TABLE_NAME,
|
|
419
|
+
s.COLUMN_NAME,
|
|
420
|
+
MAX(s.CARDINALITY) AS DISTINCT_VALUES_COUNT
|
|
421
|
+
FROM information_schema.STATISTICS s
|
|
422
|
+
WHERE s.TABLE_SCHEMA = DATABASE()
|
|
423
|
+
GROUP BY s.TABLE_SCHEMA, s.TABLE_NAME, s.COLUMN_NAME
|
|
424
|
+
)
|
|
425
|
+
SELECT
|
|
426
|
+
c.TABLE_NAME AS TABLE_NAME,
|
|
427
|
+
c.COLUMN_NAME AS COLUMN_NAME,
|
|
428
|
+
|
|
429
|
+
/* optional fields kept NULL for simplicity */
|
|
430
|
+
CAST(NULL AS JSON) AS MOST_COMMON_VALUES,
|
|
431
|
+
CAST(NULL AS JSON) AS MOST_COMMON_FREQUENCIES,
|
|
432
|
+
|
|
433
|
+
/* histogram "null-values" fraction -> percent */
|
|
434
|
+
CASE
|
|
435
|
+
WHEN h.HISTOGRAM IS NULL THEN NULL
|
|
436
|
+
ELSE ROUND(
|
|
437
|
+
CAST(JSON_UNQUOTE(JSON_EXTRACT(h.HISTOGRAM, '$."null-values"')) AS DECIMAL(10,6)) * 100,
|
|
438
|
+
2
|
|
439
|
+
)
|
|
440
|
+
END AS NULL_PERCENTAGE,
|
|
441
|
+
/* MIN: first bucket's point (singleton) or lower endpoint (equi-height) */
|
|
442
|
+
CASE
|
|
443
|
+
WHEN h.HISTOGRAM IS NULL THEN NULL
|
|
444
|
+
ELSE COALESCE(
|
|
445
|
+
JSON_UNQUOTE(JSON_EXTRACT(h.HISTOGRAM, '$.buckets[0].value')),
|
|
446
|
+
JSON_UNQUOTE(JSON_EXTRACT(h.HISTOGRAM, '$.buckets[0].endpoint[0]'))
|
|
447
|
+
)
|
|
448
|
+
END AS MINIMUM_VALUE,
|
|
449
|
+
|
|
450
|
+
/* MAX: last bucket's point (singleton) or upper endpoint (equi-height) */
|
|
451
|
+
CASE
|
|
452
|
+
WHEN h.HISTOGRAM IS NULL THEN NULL
|
|
453
|
+
ELSE COALESCE(
|
|
454
|
+
JSON_UNQUOTE(
|
|
455
|
+
JSON_EXTRACT(h.HISTOGRAM,
|
|
456
|
+
CONCAT('$.buckets[', GREATEST(h.buckets_len - 1, 0), '].value')
|
|
457
|
+
)
|
|
458
|
+
),
|
|
459
|
+
JSON_UNQUOTE(
|
|
460
|
+
JSON_EXTRACT(h.HISTOGRAM,
|
|
461
|
+
CONCAT('$.buckets[', GREATEST(h.buckets_len - 1, 0), '].endpoint[1]')
|
|
462
|
+
)
|
|
463
|
+
),
|
|
464
|
+
JSON_UNQUOTE(
|
|
465
|
+
JSON_EXTRACT(h.HISTOGRAM,
|
|
466
|
+
CONCAT('$.buckets[', GREATEST(h.buckets_len - 1, 0), '].endpoint[0]')
|
|
467
|
+
)
|
|
468
|
+
)
|
|
469
|
+
)
|
|
470
|
+
END AS MAXIMUM_VALUE,
|
|
471
|
+
n.DISTINCT_VALUES_COUNT
|
|
472
|
+
FROM cols c
|
|
473
|
+
LEFT JOIN hist h
|
|
474
|
+
ON h.TABLE_SCHEMA = c.TABLE_SCHEMA
|
|
475
|
+
AND h.TABLE_NAME = c.TABLE_NAME
|
|
476
|
+
AND h.COLUMN_NAME = c.COLUMN_NAME
|
|
477
|
+
LEFT JOIN ndv n
|
|
478
|
+
ON n.TABLE_SCHEMA = c.TABLE_SCHEMA
|
|
479
|
+
AND n.TABLE_NAME = c.TABLE_NAME
|
|
480
|
+
AND n.COLUMN_NAME = c.COLUMN_NAME
|
|
481
|
+
ORDER BY c.TABLE_NAME, c.ORDINAL_POSITION;
|
|
482
|
+
"""
|
|
483
|
+
return self.native_query(query)
|
|
484
|
+
|
|
485
|
+
def meta_get_primary_keys(self, table_names: Optional[list[str]] = None) -> Response:
|
|
486
|
+
"""
|
|
487
|
+
Retrieves primary key information for the specified tables (or all tables if no list is provided).
|
|
488
|
+
|
|
489
|
+
Args:
|
|
490
|
+
table_names (list): A list of table names for which to retrieve primary key information.
|
|
491
|
+
|
|
492
|
+
Returns:
|
|
493
|
+
Response: A response object containing the primary key information.
|
|
494
|
+
"""
|
|
495
|
+
query = """
|
|
496
|
+
SELECT
|
|
497
|
+
tc.TABLE_NAME as table_name,
|
|
498
|
+
kcu.COLUMN_NAME as column_name,
|
|
499
|
+
kcu.ORDINAL_POSITION as ordinal_position,
|
|
500
|
+
tc.CONSTRAINT_NAME as constraint_name
|
|
501
|
+
FROM information_schema.TABLE_CONSTRAINTS tc
|
|
502
|
+
INNER JOIN information_schema.KEY_COLUMN_USAGE kcu
|
|
503
|
+
ON tc.CONSTRAINT_NAME = kcu.CONSTRAINT_NAME
|
|
504
|
+
AND tc.TABLE_SCHEMA = kcu.TABLE_SCHEMA
|
|
505
|
+
AND tc.TABLE_NAME = kcu.TABLE_NAME
|
|
506
|
+
WHERE tc.CONSTRAINT_TYPE = 'PRIMARY KEY'
|
|
507
|
+
AND tc.TABLE_SCHEMA = DATABASE()
|
|
508
|
+
"""
|
|
509
|
+
|
|
510
|
+
if table_names is not None and len(table_names) > 0:
|
|
511
|
+
quoted_names = [f"'{t}'" for t in table_names]
|
|
512
|
+
query += f" AND tc.TABLE_NAME IN ({','.join(quoted_names)})"
|
|
513
|
+
|
|
514
|
+
query += " ORDER BY tc.TABLE_NAME, kcu.ORDINAL_POSITION"
|
|
515
|
+
|
|
516
|
+
result = self.native_query(query)
|
|
517
|
+
return result
|
|
518
|
+
|
|
519
|
+
def meta_get_foreign_keys(self, table_names: Optional[list[str]] = None) -> Response:
|
|
520
|
+
"""
|
|
521
|
+
Retrieves foreign key information for the specified tables (or all tables if no list is provided).
|
|
522
|
+
|
|
523
|
+
Args:
|
|
524
|
+
table_names (list): A list of table names for which to retrieve foreign key information.
|
|
525
|
+
|
|
526
|
+
Returns:
|
|
527
|
+
Response: A response object containing the foreign key information.
|
|
528
|
+
"""
|
|
529
|
+
query = """
|
|
530
|
+
SELECT
|
|
531
|
+
kcu.REFERENCED_TABLE_NAME as parent_table_name,
|
|
532
|
+
kcu.REFERENCED_COLUMN_NAME as parent_column_name,
|
|
533
|
+
kcu.TABLE_NAME as child_table_name,
|
|
534
|
+
kcu.COLUMN_NAME as child_column_name,
|
|
535
|
+
kcu.CONSTRAINT_NAME as constraint_name
|
|
536
|
+
FROM information_schema.KEY_COLUMN_USAGE kcu
|
|
537
|
+
WHERE kcu.TABLE_SCHEMA = DATABASE()
|
|
538
|
+
AND kcu.REFERENCED_TABLE_NAME IS NOT NULL
|
|
539
|
+
"""
|
|
540
|
+
|
|
541
|
+
if table_names is not None and len(table_names) > 0:
|
|
542
|
+
quoted_names = [f"'{t}'" for t in table_names]
|
|
543
|
+
query += f" AND kcu.TABLE_NAME IN ({','.join(quoted_names)})"
|
|
544
|
+
|
|
545
|
+
query += " ORDER BY kcu.TABLE_NAME, kcu.CONSTRAINT_NAME"
|
|
546
|
+
|
|
547
|
+
result = self.native_query(query)
|
|
548
|
+
return result
|
|
@@ -2,8 +2,10 @@ from mindsdb.integrations.libs.const import HANDLER_TYPE
|
|
|
2
2
|
|
|
3
3
|
from .__about__ import __version__ as version, __description__ as description
|
|
4
4
|
from .connection_args import connection_args, connection_args_example
|
|
5
|
+
|
|
5
6
|
try:
|
|
6
7
|
from .oracle_handler import OracleHandler as Handler
|
|
8
|
+
|
|
7
9
|
import_error = None
|
|
8
10
|
except Exception as e:
|
|
9
11
|
Handler = None
|
|
@@ -64,7 +64,13 @@ connection_args = OrderedDict(
|
|
|
64
64
|
"description": "Set to `true` to use thick mode for the connection. Thin mode is used by default.",
|
|
65
65
|
"required": False,
|
|
66
66
|
"label": "Connection mode",
|
|
67
|
-
}
|
|
67
|
+
},
|
|
68
|
+
oracle_client_lib_dir={
|
|
69
|
+
"type": ARG_TYPE.STR,
|
|
70
|
+
"description": "The directory path where Oracle client libraries are located. Required if using thick mode.",
|
|
71
|
+
"required": False,
|
|
72
|
+
"label": "Oracle Client Library Directory",
|
|
73
|
+
},
|
|
68
74
|
)
|
|
69
75
|
|
|
70
76
|
connection_args_example = OrderedDict(
|