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
|
@@ -21,8 +21,8 @@ logger = log.getLogger(__name__)
|
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
def _map_type(internal_type_name: str) -> MYSQL_DATA_TYPE:
|
|
24
|
-
"""
|
|
25
|
-
List of types: https://docs.oracle.com/en/database/oracle/oracle-database/
|
|
24
|
+
"""Map Oracle types to MySQL types.
|
|
25
|
+
List of types: https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/Data-Types.html
|
|
26
26
|
|
|
27
27
|
Args:
|
|
28
28
|
internal_type_name (str): The name of the Oracle type to map.
|
|
@@ -33,21 +33,33 @@ def _map_type(internal_type_name: str) -> MYSQL_DATA_TYPE:
|
|
|
33
33
|
internal_type_name = internal_type_name.upper()
|
|
34
34
|
types_map = {
|
|
35
35
|
(
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
"VARCHAR2",
|
|
37
|
+
"NVARCHAR2",
|
|
38
|
+
"CHARACTER VARYING",
|
|
39
|
+
"CHAR VARYING",
|
|
40
|
+
"NATIONAL CHARACTER",
|
|
41
|
+
"NATIONAL CHAR",
|
|
42
|
+
"VARCHAR",
|
|
43
|
+
"NCHAR",
|
|
44
|
+
"NATIONAL CHARACTER VARYING",
|
|
45
|
+
"NATIONAL CHAR VARYING",
|
|
46
|
+
"NCHAR VARYING",
|
|
47
|
+
"LONG VARCHAR",
|
|
38
48
|
): MYSQL_DATA_TYPE.VARCHAR,
|
|
39
|
-
(
|
|
40
|
-
(
|
|
41
|
-
(
|
|
42
|
-
(
|
|
43
|
-
(
|
|
44
|
-
(
|
|
45
|
-
(
|
|
46
|
-
(
|
|
47
|
-
(
|
|
48
|
-
(
|
|
49
|
-
(
|
|
50
|
-
(
|
|
49
|
+
("INTEGER", "INT"): MYSQL_DATA_TYPE.INT,
|
|
50
|
+
("SMALLINT",): MYSQL_DATA_TYPE.SMALLINT,
|
|
51
|
+
("NUMBER", "DECIMAL"): MYSQL_DATA_TYPE.DECIMAL,
|
|
52
|
+
("FLOAT", "BINARY_FLOAT", "REAL"): MYSQL_DATA_TYPE.FLOAT,
|
|
53
|
+
("BINARY_DOUBLE",): MYSQL_DATA_TYPE.DOUBLE,
|
|
54
|
+
("LONG",): MYSQL_DATA_TYPE.BIGINT,
|
|
55
|
+
("DATE",): MYSQL_DATA_TYPE.DATE,
|
|
56
|
+
("HOUR", "MINUTE", "SECOND", "TIMEZONE_HOUR", "TIMEZONE_MINUTE"): MYSQL_DATA_TYPE.SMALLINT,
|
|
57
|
+
("TIMESTAMP", "TIMESTAMP WITH TIME ZONE", "TIMESTAMP WITH LOCAL TIME ZONE"): MYSQL_DATA_TYPE.TIMESTAMP,
|
|
58
|
+
("RAW", "LONG RAW", "BLOB", "BFILE"): MYSQL_DATA_TYPE.BINARY,
|
|
59
|
+
("ROWID", "UROWID"): MYSQL_DATA_TYPE.TEXT,
|
|
60
|
+
("CHAR", "NCHAR", "CLOB", "NCLOB", "CHARACTER"): MYSQL_DATA_TYPE.CHAR,
|
|
61
|
+
("VECTOR",): MYSQL_DATA_TYPE.VECTOR,
|
|
62
|
+
("JSON",): MYSQL_DATA_TYPE.JSON,
|
|
51
63
|
}
|
|
52
64
|
|
|
53
65
|
for db_types_list, mysql_data_type in types_map.items():
|
|
@@ -74,7 +86,11 @@ def _make_table_response(result: list[tuple[Any]], cursor: Cursor) -> Response:
|
|
|
74
86
|
db_type = column[1]
|
|
75
87
|
precision = column[4]
|
|
76
88
|
scale = column[5]
|
|
77
|
-
if db_type is oracledb.
|
|
89
|
+
if db_type is oracledb.DB_TYPE_JSON:
|
|
90
|
+
mysql_types.append(MYSQL_DATA_TYPE.JSON)
|
|
91
|
+
elif db_type is oracledb.DB_TYPE_VECTOR:
|
|
92
|
+
mysql_types.append(MYSQL_DATA_TYPE.VECTOR)
|
|
93
|
+
elif db_type is oracledb.DB_TYPE_NUMBER:
|
|
78
94
|
if scale != 0:
|
|
79
95
|
mysql_types.append(MYSQL_DATA_TYPE.FLOAT)
|
|
80
96
|
else:
|
|
@@ -92,8 +108,12 @@ def _make_table_response(result: list[tuple[Any]], cursor: Cursor) -> Response:
|
|
|
92
108
|
elif db_type is oracledb.DB_TYPE_BOOLEAN:
|
|
93
109
|
mysql_types.append(MYSQL_DATA_TYPE.BOOLEAN)
|
|
94
110
|
elif db_type in (
|
|
95
|
-
oracledb.DB_TYPE_CHAR,
|
|
96
|
-
oracledb.
|
|
111
|
+
oracledb.DB_TYPE_CHAR,
|
|
112
|
+
oracledb.DB_TYPE_NCHAR,
|
|
113
|
+
oracledb.DB_TYPE_LONG,
|
|
114
|
+
oracledb.DB_TYPE_NVARCHAR,
|
|
115
|
+
oracledb.DB_TYPE_VARCHAR,
|
|
116
|
+
oracledb.DB_TYPE_LONG_NVARCHAR,
|
|
97
117
|
):
|
|
98
118
|
mysql_types.append(MYSQL_DATA_TYPE.TEXT)
|
|
99
119
|
elif db_type in (oracledb.DB_TYPE_RAW, oracledb.DB_TYPE_LONG_RAW):
|
|
@@ -111,21 +131,20 @@ def _make_table_response(result: list[tuple[Any]], cursor: Cursor) -> Response:
|
|
|
111
131
|
for i, mysql_type in enumerate(mysql_types):
|
|
112
132
|
expected_dtype = None
|
|
113
133
|
if mysql_type in (
|
|
114
|
-
MYSQL_DATA_TYPE.SMALLINT,
|
|
115
|
-
MYSQL_DATA_TYPE.
|
|
134
|
+
MYSQL_DATA_TYPE.SMALLINT,
|
|
135
|
+
MYSQL_DATA_TYPE.INT,
|
|
136
|
+
MYSQL_DATA_TYPE.MEDIUMINT,
|
|
137
|
+
MYSQL_DATA_TYPE.BIGINT,
|
|
138
|
+
MYSQL_DATA_TYPE.TINYINT,
|
|
116
139
|
):
|
|
117
|
-
expected_dtype =
|
|
140
|
+
expected_dtype = "Int64"
|
|
118
141
|
elif mysql_type in (MYSQL_DATA_TYPE.BOOL, MYSQL_DATA_TYPE.BOOLEAN):
|
|
119
|
-
expected_dtype =
|
|
142
|
+
expected_dtype = "boolean"
|
|
120
143
|
serieses.append(pd.Series([row[i] for row in result], dtype=expected_dtype, name=description[i][0]))
|
|
121
144
|
df = pd.concat(serieses, axis=1, copy=False)
|
|
122
145
|
# endregion
|
|
123
146
|
|
|
124
|
-
return Response(
|
|
125
|
-
RESPONSE_TYPE.TABLE,
|
|
126
|
-
data_frame=df,
|
|
127
|
-
mysql_types=mysql_types
|
|
128
|
-
)
|
|
147
|
+
return Response(RESPONSE_TYPE.TABLE, data_frame=df, mysql_types=mysql_types)
|
|
129
148
|
|
|
130
149
|
|
|
131
150
|
class OracleHandler(DatabaseHandler):
|
|
@@ -165,59 +184,63 @@ class OracleHandler(DatabaseHandler):
|
|
|
165
184
|
return self.connection
|
|
166
185
|
|
|
167
186
|
# Mandatory connection parameters.
|
|
168
|
-
if not all(key in self.connection_data for key in [
|
|
169
|
-
raise ValueError(
|
|
187
|
+
if not all(key in self.connection_data for key in ["user", "password"]):
|
|
188
|
+
raise ValueError("Required parameters (user, password) must be provided.")
|
|
170
189
|
|
|
171
|
-
if self.connection_data.get(
|
|
190
|
+
if self.connection_data.get("thick_mode", False):
|
|
172
191
|
oracledb.init_oracle_client()
|
|
173
192
|
|
|
174
193
|
config = {
|
|
175
|
-
|
|
176
|
-
|
|
194
|
+
"user": self.connection_data["user"],
|
|
195
|
+
"password": self.connection_data["password"],
|
|
177
196
|
}
|
|
178
197
|
|
|
179
198
|
# If 'dsn' is given, use it. Otherwise, use the individual connection parameters.
|
|
180
|
-
if
|
|
181
|
-
config[
|
|
199
|
+
if "dsn" in self.connection_data:
|
|
200
|
+
config["dsn"] = self.connection_data["dsn"]
|
|
182
201
|
|
|
183
202
|
else:
|
|
184
|
-
if
|
|
185
|
-
|
|
203
|
+
if "host" not in self.connection_data and not any(
|
|
204
|
+
key in self.connection_data for key in ["sid", "service_name"]
|
|
205
|
+
):
|
|
206
|
+
raise ValueError(
|
|
207
|
+
"Required parameter host and either sid or service_name must be provided. Alternatively, dsn can be provided."
|
|
208
|
+
)
|
|
186
209
|
|
|
187
|
-
config[
|
|
210
|
+
config["host"] = self.connection_data.get("host")
|
|
188
211
|
|
|
189
212
|
# Optional connection parameters when 'dsn' is not given.
|
|
190
|
-
optional_parameters = [
|
|
213
|
+
optional_parameters = ["port", "sid", "service_name"]
|
|
191
214
|
for parameter in optional_parameters:
|
|
192
215
|
if parameter in self.connection_data:
|
|
193
216
|
config[parameter] = self.connection_data[parameter]
|
|
194
217
|
|
|
195
218
|
# Other optional connection parameters.
|
|
196
|
-
if
|
|
197
|
-
config[
|
|
219
|
+
if "disable_oob" in self.connection_data:
|
|
220
|
+
config["disable_oob"] = self.connection_data["disable_oob"]
|
|
198
221
|
|
|
199
|
-
if
|
|
200
|
-
mode_name =
|
|
222
|
+
if "auth_mode" in self.connection_data:
|
|
223
|
+
mode_name = "AUTH_MODE_" + self.connection_data["auth_mode"].upper()
|
|
201
224
|
if not hasattr(oracledb, mode_name):
|
|
202
|
-
raise ValueError(f
|
|
203
|
-
config[
|
|
225
|
+
raise ValueError(f"Unknown auth mode: {mode_name}")
|
|
226
|
+
config["mode"] = getattr(oracledb, mode_name)
|
|
204
227
|
|
|
205
228
|
try:
|
|
206
229
|
connection = connect(
|
|
207
230
|
**config,
|
|
208
231
|
)
|
|
209
232
|
|
|
210
|
-
if
|
|
233
|
+
if "session_variables" in self.connection_data:
|
|
211
234
|
with connection.cursor() as cur:
|
|
212
|
-
for key, value in self.connection_data[
|
|
235
|
+
for key, value in self.connection_data["session_variables"].items():
|
|
213
236
|
cur.execute(f"ALTER SESSION SET {key} = {repr(value)}")
|
|
214
237
|
|
|
215
238
|
except DatabaseError as database_error:
|
|
216
|
-
logger.error(f
|
|
239
|
+
logger.error(f"Error connecting to Oracle, {database_error}!")
|
|
217
240
|
raise
|
|
218
241
|
|
|
219
242
|
except Exception as unknown_error:
|
|
220
|
-
logger.error(f
|
|
243
|
+
logger.error(f"Unknown error when connecting to Elasticsearch: {unknown_error}")
|
|
221
244
|
raise
|
|
222
245
|
|
|
223
246
|
self.is_connected = True
|
|
@@ -248,10 +271,10 @@ class OracleHandler(DatabaseHandler):
|
|
|
248
271
|
con.ping()
|
|
249
272
|
response.success = True
|
|
250
273
|
except (ValueError, DatabaseError) as known_error:
|
|
251
|
-
logger.error(f
|
|
274
|
+
logger.error(f"Connection check to Oracle failed, {known_error}!")
|
|
252
275
|
response.error_message = str(known_error)
|
|
253
276
|
except Exception as unknown_error:
|
|
254
|
-
logger.error(f
|
|
277
|
+
logger.error(f"Connection check to Oracle failed due to an unknown error, {unknown_error}!")
|
|
255
278
|
response.error_message = str(unknown_error)
|
|
256
279
|
|
|
257
280
|
if response.success and need_to_close:
|