MindsDB 25.5.4.2__py3-none-any.whl → 25.6.2.0__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/api/a2a/agent.py +28 -25
- mindsdb/api/a2a/common/server/server.py +32 -26
- mindsdb/api/executor/command_executor.py +69 -14
- mindsdb/api/executor/datahub/datanodes/integration_datanode.py +49 -65
- mindsdb/api/executor/datahub/datanodes/project_datanode.py +29 -48
- mindsdb/api/executor/datahub/datanodes/system_tables.py +35 -61
- mindsdb/api/executor/planner/plan_join.py +67 -77
- mindsdb/api/executor/planner/query_planner.py +176 -155
- mindsdb/api/executor/planner/steps.py +37 -12
- mindsdb/api/executor/sql_query/result_set.py +45 -64
- mindsdb/api/executor/sql_query/steps/fetch_dataframe.py +14 -18
- mindsdb/api/executor/sql_query/steps/fetch_dataframe_partition.py +17 -18
- mindsdb/api/executor/sql_query/steps/insert_step.py +13 -33
- mindsdb/api/executor/sql_query/steps/subselect_step.py +43 -35
- mindsdb/api/executor/utilities/sql.py +42 -48
- mindsdb/api/http/namespaces/config.py +1 -1
- mindsdb/api/http/namespaces/file.py +14 -23
- mindsdb/api/mysql/mysql_proxy/data_types/mysql_datum.py +12 -28
- mindsdb/api/mysql/mysql_proxy/data_types/mysql_packets/binary_resultset_row_package.py +59 -50
- mindsdb/api/mysql/mysql_proxy/data_types/mysql_packets/resultset_row_package.py +9 -8
- mindsdb/api/mysql/mysql_proxy/libs/constants/mysql.py +449 -461
- mindsdb/api/mysql/mysql_proxy/utilities/dump.py +87 -36
- mindsdb/integrations/handlers/file_handler/file_handler.py +15 -9
- mindsdb/integrations/handlers/file_handler/tests/test_file_handler.py +43 -24
- mindsdb/integrations/handlers/litellm_handler/litellm_handler.py +10 -3
- mindsdb/integrations/handlers/mysql_handler/mysql_handler.py +26 -33
- mindsdb/integrations/handlers/oracle_handler/oracle_handler.py +74 -51
- mindsdb/integrations/handlers/postgres_handler/postgres_handler.py +305 -98
- mindsdb/integrations/handlers/salesforce_handler/salesforce_handler.py +53 -34
- mindsdb/integrations/handlers/salesforce_handler/salesforce_tables.py +136 -6
- mindsdb/integrations/handlers/snowflake_handler/snowflake_handler.py +334 -83
- mindsdb/integrations/libs/api_handler.py +261 -57
- mindsdb/integrations/libs/base.py +100 -29
- mindsdb/integrations/utilities/files/file_reader.py +99 -73
- mindsdb/integrations/utilities/handler_utils.py +23 -8
- mindsdb/integrations/utilities/sql_utils.py +35 -40
- mindsdb/interfaces/agents/agents_controller.py +196 -192
- mindsdb/interfaces/agents/constants.py +7 -1
- mindsdb/interfaces/agents/langchain_agent.py +42 -11
- mindsdb/interfaces/agents/mcp_client_agent.py +29 -21
- mindsdb/interfaces/data_catalog/__init__.py +0 -0
- mindsdb/interfaces/data_catalog/base_data_catalog.py +54 -0
- mindsdb/interfaces/data_catalog/data_catalog_loader.py +359 -0
- mindsdb/interfaces/data_catalog/data_catalog_reader.py +34 -0
- mindsdb/interfaces/database/database.py +81 -57
- mindsdb/interfaces/database/integrations.py +220 -234
- mindsdb/interfaces/database/log.py +72 -104
- mindsdb/interfaces/database/projects.py +156 -193
- mindsdb/interfaces/file/file_controller.py +21 -65
- mindsdb/interfaces/knowledge_base/controller.py +63 -10
- mindsdb/interfaces/knowledge_base/evaluate.py +519 -0
- mindsdb/interfaces/knowledge_base/llm_client.py +75 -0
- mindsdb/interfaces/skills/custom/text2sql/mindsdb_kb_tools.py +83 -43
- mindsdb/interfaces/skills/skills_controller.py +54 -36
- mindsdb/interfaces/skills/sql_agent.py +109 -86
- mindsdb/interfaces/storage/db.py +223 -79
- mindsdb/migrations/versions/2025-05-28_a44643042fe8_added_data_catalog_tables.py +118 -0
- mindsdb/migrations/versions/2025-06-09_608e376c19a7_updated_data_catalog_data_types.py +58 -0
- mindsdb/utilities/config.py +9 -2
- mindsdb/utilities/log.py +35 -26
- mindsdb/utilities/ml_task_queue/task.py +19 -22
- mindsdb/utilities/render/sqlalchemy_render.py +129 -181
- mindsdb/utilities/starters.py +40 -0
- {mindsdb-25.5.4.2.dist-info → mindsdb-25.6.2.0.dist-info}/METADATA +253 -253
- {mindsdb-25.5.4.2.dist-info → mindsdb-25.6.2.0.dist-info}/RECORD +69 -61
- {mindsdb-25.5.4.2.dist-info → mindsdb-25.6.2.0.dist-info}/WHEEL +0 -0
- {mindsdb-25.5.4.2.dist-info → mindsdb-25.6.2.0.dist-info}/licenses/LICENSE +0 -0
- {mindsdb-25.5.4.2.dist-info → mindsdb-25.6.2.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
from mindsdb.interfaces.data_catalog.base_data_catalog import BaseDataCatalog
|
|
2
|
+
from mindsdb.interfaces.storage import db
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class DataCatalogReader(BaseDataCatalog):
|
|
6
|
+
"""
|
|
7
|
+
This class is responsible for reading the metadata from the data catalog and providing it in a structured format.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
def read_metadata_as_string(self) -> str:
|
|
11
|
+
"""
|
|
12
|
+
Read the metadata from the data catalog and return it as a string.
|
|
13
|
+
"""
|
|
14
|
+
if not self.is_data_catalog_supported():
|
|
15
|
+
return f"Data catalog is not supported for database '{self.database_name}'."
|
|
16
|
+
tables = self._read_metadata()
|
|
17
|
+
if not tables:
|
|
18
|
+
self.logger.warning(f"No metadata found for database '{self.database_name}'")
|
|
19
|
+
return f"No metadata found for database '{self.database_name}'"
|
|
20
|
+
metadata_str = "Data Catalog: \n"
|
|
21
|
+
for table in tables:
|
|
22
|
+
metadata_str += table.as_string() + "\n\n"
|
|
23
|
+
return metadata_str
|
|
24
|
+
|
|
25
|
+
def _read_metadata(self) -> list:
|
|
26
|
+
"""
|
|
27
|
+
Read the metadata from the data catalog and return it in a structured format.
|
|
28
|
+
"""
|
|
29
|
+
query = db.session.query(db.MetaTables).filter_by(integration_id=self.integration_id)
|
|
30
|
+
if self.table_names:
|
|
31
|
+
cleaned_table_names = [name.strip("`").split(".")[-1] for name in self.table_names]
|
|
32
|
+
query = query.filter(db.MetaTables.name.in_(cleaned_table_names))
|
|
33
|
+
tables = query.all()
|
|
34
|
+
return tables
|
|
@@ -11,6 +11,7 @@ from mindsdb.interfaces.database.log import LogDBController
|
|
|
11
11
|
class DatabaseController:
|
|
12
12
|
def __init__(self):
|
|
13
13
|
from mindsdb.interfaces.database.integrations import integration_controller
|
|
14
|
+
|
|
14
15
|
self.integration_controller = integration_controller
|
|
15
16
|
self.project_controller = ProjectController()
|
|
16
17
|
|
|
@@ -21,13 +22,13 @@ class DatabaseController:
|
|
|
21
22
|
databases = self.get_dict()
|
|
22
23
|
name = name.lower()
|
|
23
24
|
if name not in databases:
|
|
24
|
-
raise EntityNotExistsError(
|
|
25
|
-
db_type = databases[name][
|
|
26
|
-
if db_type ==
|
|
25
|
+
raise EntityNotExistsError("Database does not exists", name)
|
|
26
|
+
db_type = databases[name]["type"]
|
|
27
|
+
if db_type == "project":
|
|
27
28
|
project = self.get_project(name)
|
|
28
29
|
project.delete()
|
|
29
30
|
return
|
|
30
|
-
elif db_type ==
|
|
31
|
+
elif db_type == "data":
|
|
31
32
|
self.integration_controller.delete(name)
|
|
32
33
|
return
|
|
33
34
|
else:
|
|
@@ -37,59 +38,52 @@ class DatabaseController:
|
|
|
37
38
|
def get_list(self, filter_type: Optional[str] = None, with_secrets: Optional[bool] = True):
|
|
38
39
|
projects = self.project_controller.get_list()
|
|
39
40
|
integrations = self.integration_controller.get_all(show_secrets=with_secrets)
|
|
40
|
-
result = [
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
'engine': None,
|
|
52
|
-
'visible': True,
|
|
53
|
-
'deletable': False
|
|
54
|
-
}]
|
|
41
|
+
result = [
|
|
42
|
+
{
|
|
43
|
+
"name": "information_schema",
|
|
44
|
+
"type": "system",
|
|
45
|
+
"id": None,
|
|
46
|
+
"engine": None,
|
|
47
|
+
"visible": True,
|
|
48
|
+
"deletable": False,
|
|
49
|
+
},
|
|
50
|
+
{"name": "log", "type": "system", "id": None, "engine": None, "visible": True, "deletable": False},
|
|
51
|
+
]
|
|
55
52
|
for x in projects:
|
|
56
|
-
result.append(
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
53
|
+
result.append(
|
|
54
|
+
{
|
|
55
|
+
"name": x.name,
|
|
56
|
+
"type": "project",
|
|
57
|
+
"id": x.id,
|
|
58
|
+
"engine": None,
|
|
59
|
+
"visible": True,
|
|
60
|
+
"deletable": x.name.lower() != config.get("default_project"),
|
|
61
|
+
}
|
|
62
|
+
)
|
|
64
63
|
for key, value in integrations.items():
|
|
65
|
-
db_type = value.get(
|
|
66
|
-
if db_type !=
|
|
67
|
-
result.append(
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
64
|
+
db_type = value.get("type", "data")
|
|
65
|
+
if db_type != "ml":
|
|
66
|
+
result.append(
|
|
67
|
+
{
|
|
68
|
+
"name": key,
|
|
69
|
+
"type": value.get("type", "data"),
|
|
70
|
+
"id": value.get("id"),
|
|
71
|
+
"engine": value.get("engine"),
|
|
72
|
+
"class_type": value.get("class_type"),
|
|
73
|
+
"connection_data": value.get("connection_data"),
|
|
74
|
+
"visible": True,
|
|
75
|
+
"deletable": value.get("permanent", False) is False,
|
|
76
|
+
}
|
|
77
|
+
)
|
|
77
78
|
|
|
78
79
|
if filter_type is not None:
|
|
79
|
-
result = [x for x in result if x[
|
|
80
|
+
result = [x for x in result if x["type"] == filter_type]
|
|
80
81
|
|
|
81
82
|
return result
|
|
82
83
|
|
|
83
84
|
def get_dict(self, filter_type: Optional[str] = None):
|
|
84
85
|
return OrderedDict(
|
|
85
|
-
(
|
|
86
|
-
x['name'].lower(),
|
|
87
|
-
{
|
|
88
|
-
'type': x['type'],
|
|
89
|
-
'engine': x['engine'],
|
|
90
|
-
'id': x['id']
|
|
91
|
-
}
|
|
92
|
-
)
|
|
86
|
+
(x["name"].lower(), {"type": x["type"], "engine": x["engine"], "id": x["id"]})
|
|
93
87
|
for x in self.get_list(filter_type=filter_type)
|
|
94
88
|
)
|
|
95
89
|
|
|
@@ -98,13 +92,8 @@ class DatabaseController:
|
|
|
98
92
|
|
|
99
93
|
# TODO get directly from db?
|
|
100
94
|
for rec in self.get_list():
|
|
101
|
-
if rec[
|
|
102
|
-
return {
|
|
103
|
-
'name': rec['name'],
|
|
104
|
-
'type': rec['type'],
|
|
105
|
-
'engine': rec['engine'],
|
|
106
|
-
'id': rec['id']
|
|
107
|
-
}
|
|
95
|
+
if rec["id"] == integration_id and rec["type"] == "data":
|
|
96
|
+
return {"name": rec["name"], "type": rec["type"], "engine": rec["engine"], "id": rec["id"]}
|
|
108
97
|
|
|
109
98
|
def exists(self, db_name: str) -> bool:
|
|
110
99
|
return db_name.lower() in self.get_dict()
|
|
@@ -113,11 +102,46 @@ class DatabaseController:
|
|
|
113
102
|
return self.project_controller.get(name=name)
|
|
114
103
|
|
|
115
104
|
def get_system_db(self, name: str):
|
|
116
|
-
if name ==
|
|
105
|
+
if name == "log":
|
|
117
106
|
return self.logs_db_controller
|
|
118
|
-
elif name ==
|
|
107
|
+
elif name == "information_schema":
|
|
119
108
|
from mindsdb.api.executor.controllers.session_controller import SessionController
|
|
109
|
+
|
|
120
110
|
session = SessionController()
|
|
121
111
|
return session.datahub
|
|
122
112
|
else:
|
|
123
113
|
raise Exception(f"Database '{name}' does not exists")
|
|
114
|
+
|
|
115
|
+
def update(self, name: str, data: dict):
|
|
116
|
+
"""
|
|
117
|
+
Updates the database with the given name using the provided data.
|
|
118
|
+
|
|
119
|
+
Parameters:
|
|
120
|
+
name (str): The name of the database to update.
|
|
121
|
+
data (dict): The data to update the database with.
|
|
122
|
+
|
|
123
|
+
Raises:
|
|
124
|
+
EntityNotExistsError: If the database does not exist.
|
|
125
|
+
"""
|
|
126
|
+
databases = self.get_dict()
|
|
127
|
+
name = name.lower()
|
|
128
|
+
if name not in databases:
|
|
129
|
+
raise EntityNotExistsError("Database does not exist.", name)
|
|
130
|
+
|
|
131
|
+
db_type = databases[name]["type"]
|
|
132
|
+
if db_type == "project":
|
|
133
|
+
# Only the name of the project can be updated.
|
|
134
|
+
if {"name"} != set(data):
|
|
135
|
+
raise ValueError("Only the 'name' field can be updated for projects.")
|
|
136
|
+
self.project_controller.update(name=name, new_name=str(data["name"]))
|
|
137
|
+
return
|
|
138
|
+
|
|
139
|
+
elif db_type == "data":
|
|
140
|
+
# Only the parameters (connection data) of the integration can be updated.
|
|
141
|
+
if {"parameters"} != set(data):
|
|
142
|
+
raise ValueError("Only the 'parameters' field can be updated for integrations.")
|
|
143
|
+
self.integration_controller.modify(name, data["parameters"])
|
|
144
|
+
return
|
|
145
|
+
|
|
146
|
+
else:
|
|
147
|
+
raise ValueError(f"Database with type '{db_type}' cannot be updated")
|