MindsDB 25.5.3.0__py3-none-any.whl → 25.5.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.
Potentially problematic release.
This version of MindsDB might be problematic. Click here for more details.
- mindsdb/__about__.py +8 -8
- mindsdb/__main__.py +127 -79
- mindsdb/api/a2a/__init__.py +0 -0
- mindsdb/api/a2a/__main__.py +144 -0
- mindsdb/api/a2a/agent.py +308 -0
- mindsdb/api/a2a/common/__init__.py +0 -0
- mindsdb/api/a2a/common/server/__init__.py +4 -0
- mindsdb/api/a2a/common/server/server.py +164 -0
- mindsdb/api/a2a/common/server/task_manager.py +287 -0
- mindsdb/api/a2a/common/server/utils.py +28 -0
- mindsdb/api/a2a/common/types.py +365 -0
- mindsdb/api/a2a/constants.py +9 -0
- mindsdb/api/a2a/run_a2a.py +86 -0
- mindsdb/api/a2a/task_manager.py +560 -0
- mindsdb/api/executor/command_executor.py +185 -309
- mindsdb/api/executor/datahub/classes/response.py +5 -2
- mindsdb/api/executor/datahub/datanodes/integration_datanode.py +39 -72
- mindsdb/api/executor/planner/query_planner.py +10 -1
- mindsdb/api/executor/sql_query/result_set.py +185 -52
- mindsdb/api/executor/sql_query/sql_query.py +1 -1
- mindsdb/api/executor/sql_query/steps/apply_predictor_step.py +9 -12
- mindsdb/api/executor/sql_query/steps/fetch_dataframe.py +8 -10
- mindsdb/api/executor/sql_query/steps/fetch_dataframe_partition.py +5 -44
- mindsdb/api/executor/sql_query/steps/insert_step.py +24 -15
- mindsdb/api/executor/sql_query/steps/join_step.py +1 -1
- mindsdb/api/executor/sql_query/steps/project_step.py +1 -1
- mindsdb/api/executor/sql_query/steps/sql_steps.py +1 -1
- mindsdb/api/executor/sql_query/steps/subselect_step.py +4 -8
- mindsdb/api/executor/sql_query/steps/union_step.py +1 -3
- mindsdb/api/http/initialize.py +99 -83
- mindsdb/api/http/namespaces/analysis.py +3 -3
- mindsdb/api/http/namespaces/config.py +61 -86
- mindsdb/api/http/namespaces/file.py +8 -2
- mindsdb/api/http/namespaces/sql.py +13 -27
- mindsdb/api/mcp/start.py +42 -5
- mindsdb/api/mysql/mysql_proxy/data_types/mysql_packet.py +0 -1
- mindsdb/api/mysql/mysql_proxy/data_types/mysql_packets/binary_resultset_row_package.py +52 -19
- mindsdb/api/mysql/mysql_proxy/executor/mysql_executor.py +8 -10
- mindsdb/api/mysql/mysql_proxy/libs/constants/mysql.py +54 -38
- mindsdb/api/mysql/mysql_proxy/mysql_proxy.py +82 -115
- mindsdb/api/mysql/mysql_proxy/utilities/dump.py +351 -0
- mindsdb/api/postgres/postgres_proxy/executor/executor.py +1 -1
- mindsdb/api/postgres/postgres_proxy/postgres_proxy.py +5 -6
- mindsdb/integrations/handlers/altibase_handler/altibase_handler.py +26 -27
- mindsdb/integrations/handlers/altibase_handler/connection_args.py +13 -13
- mindsdb/integrations/handlers/altibase_handler/tests/test_altibase_handler.py +8 -8
- mindsdb/integrations/handlers/altibase_handler/tests/test_altibase_handler_dsn.py +13 -13
- mindsdb/integrations/handlers/anthropic_handler/__init__.py +2 -2
- mindsdb/integrations/handlers/anthropic_handler/anthropic_handler.py +1 -3
- mindsdb/integrations/handlers/aurora_handler/aurora_handler.py +1 -0
- mindsdb/integrations/handlers/autosklearn_handler/autosklearn_handler.py +1 -1
- mindsdb/integrations/handlers/autosklearn_handler/config.py +0 -1
- mindsdb/integrations/handlers/bigquery_handler/bigquery_handler.py +1 -1
- mindsdb/integrations/handlers/bigquery_handler/tests/test_bigquery_handler.py +1 -1
- mindsdb/integrations/handlers/binance_handler/binance_handler.py +1 -0
- mindsdb/integrations/handlers/binance_handler/binance_tables.py +3 -4
- mindsdb/integrations/handlers/byom_handler/__init__.py +0 -1
- mindsdb/integrations/handlers/byom_handler/requirements.txt +1 -2
- mindsdb/integrations/handlers/ckan_handler/ckan_handler.py +3 -0
- mindsdb/integrations/handlers/clickhouse_handler/__init__.py +1 -1
- mindsdb/integrations/handlers/cloud_spanner_handler/tests/test_cloud_spanner_handler.py +0 -2
- mindsdb/integrations/handlers/cloud_sql_handler/cloud_sql_handler.py +0 -1
- mindsdb/integrations/handlers/cohere_handler/__init__.py +1 -1
- mindsdb/integrations/handlers/cohere_handler/cohere_handler.py +11 -13
- mindsdb/integrations/handlers/confluence_handler/confluence_tables.py +6 -0
- mindsdb/integrations/handlers/databend_handler/connection_args.py +1 -1
- mindsdb/integrations/handlers/databend_handler/databend_handler.py +4 -4
- mindsdb/integrations/handlers/databend_handler/tests/__init__.py +0 -1
- mindsdb/integrations/handlers/databend_handler/tests/test_databend_handler.py +1 -1
- mindsdb/integrations/handlers/derby_handler/connection_args.py +1 -1
- mindsdb/integrations/handlers/derby_handler/derby_handler.py +14 -22
- mindsdb/integrations/handlers/derby_handler/tests/test_derby_handler.py +6 -6
- mindsdb/integrations/handlers/discord_handler/discord_handler.py +5 -5
- mindsdb/integrations/handlers/discord_handler/discord_tables.py +3 -3
- mindsdb/integrations/handlers/discord_handler/tests/test_discord.py +5 -3
- mindsdb/integrations/handlers/dockerhub_handler/dockerhub.py +3 -3
- mindsdb/integrations/handlers/dockerhub_handler/dockerhub_handler.py +2 -2
- mindsdb/integrations/handlers/dockerhub_handler/dockerhub_tables.py +57 -54
- mindsdb/integrations/handlers/dremio_handler/__init__.py +2 -2
- mindsdb/integrations/handlers/druid_handler/__init__.py +1 -1
- mindsdb/integrations/handlers/druid_handler/druid_handler.py +2 -2
- mindsdb/integrations/handlers/edgelessdb_handler/tests/test_edgelessdb_handler.py +9 -9
- mindsdb/integrations/handlers/email_handler/email_client.py +1 -1
- mindsdb/integrations/handlers/email_handler/email_ingestor.py +1 -1
- mindsdb/integrations/handlers/email_handler/email_tables.py +0 -1
- mindsdb/integrations/handlers/email_handler/settings.py +0 -1
- mindsdb/integrations/handlers/eventstoredb_handler/eventstoredb_handler.py +2 -1
- mindsdb/integrations/handlers/firebird_handler/firebird_handler.py +1 -1
- mindsdb/integrations/handlers/flaml_handler/flaml_handler.py +9 -9
- mindsdb/integrations/handlers/frappe_handler/frappe_client.py +5 -5
- mindsdb/integrations/handlers/frappe_handler/frappe_handler.py +6 -5
- mindsdb/integrations/handlers/frappe_handler/frappe_tables.py +2 -2
- mindsdb/integrations/handlers/github_handler/connection_args.py +2 -2
- mindsdb/integrations/handlers/github_handler/github_handler.py +1 -8
- mindsdb/integrations/handlers/github_handler/github_tables.py +13 -24
- mindsdb/integrations/handlers/gitlab_handler/gitlab_handler.py +2 -1
- mindsdb/integrations/handlers/gitlab_handler/gitlab_tables.py +1 -4
- mindsdb/integrations/handlers/gmail_handler/gmail_handler.py +6 -13
- mindsdb/integrations/handlers/google_books_handler/google_books_handler.py +2 -1
- mindsdb/integrations/handlers/google_books_handler/google_books_tables.py +0 -3
- mindsdb/integrations/handlers/google_calendar_handler/google_calendar_handler.py +4 -4
- mindsdb/integrations/handlers/google_calendar_handler/google_calendar_tables.py +2 -6
- mindsdb/integrations/handlers/google_content_shopping_handler/google_content_shopping_handler.py +3 -2
- mindsdb/integrations/handlers/google_content_shopping_handler/google_content_shopping_tables.py +0 -3
- mindsdb/integrations/handlers/google_fit_handler/google_fit_handler.py +10 -12
- mindsdb/integrations/handlers/google_fit_handler/google_fit_tables.py +11 -13
- mindsdb/integrations/handlers/google_search_handler/google_search_handler.py +2 -1
- mindsdb/integrations/handlers/google_search_handler/google_search_tables.py +0 -3
- mindsdb/integrations/handlers/groq_handler/__init__.py +3 -3
- mindsdb/integrations/handlers/hackernews_handler/hn_handler.py +5 -7
- mindsdb/integrations/handlers/hackernews_handler/hn_table.py +6 -7
- mindsdb/integrations/handlers/hive_handler/tests/test_hive_handler.py +1 -1
- mindsdb/integrations/handlers/hsqldb_handler/connection_args.py +6 -6
- mindsdb/integrations/handlers/hsqldb_handler/hsqldb_handler.py +4 -3
- mindsdb/integrations/handlers/huggingface_api_handler/exceptions.py +1 -1
- mindsdb/integrations/handlers/huggingface_api_handler/huggingface_api_handler.py +1 -8
- mindsdb/integrations/handlers/huggingface_handler/huggingface_handler.py +6 -6
- mindsdb/integrations/handlers/huggingface_handler/requirements.txt +1 -1
- mindsdb/integrations/handlers/huggingface_handler/requirements_cpu.txt +1 -1
- mindsdb/integrations/handlers/ignite_handler/ignite_handler.py +2 -1
- mindsdb/integrations/handlers/impala_handler/impala_handler.py +9 -12
- mindsdb/integrations/handlers/impala_handler/tests/test_impala_handler.py +11 -11
- mindsdb/integrations/handlers/influxdb_handler/influxdb_handler.py +10 -13
- mindsdb/integrations/handlers/influxdb_handler/influxdb_tables.py +20 -20
- mindsdb/integrations/handlers/informix_handler/__about__.py +8 -8
- mindsdb/integrations/handlers/informix_handler/__init__.py +12 -5
- mindsdb/integrations/handlers/informix_handler/informix_handler.py +99 -133
- mindsdb/integrations/handlers/informix_handler/tests/test_informix_handler.py +13 -11
- mindsdb/integrations/handlers/ingres_handler/__about__.py +0 -1
- mindsdb/integrations/handlers/ingres_handler/ingres_handler.py +1 -0
- mindsdb/integrations/handlers/jira_handler/jira_handler.py +4 -4
- mindsdb/integrations/handlers/jira_handler/jira_tables.py +9 -9
- mindsdb/integrations/handlers/kinetica_handler/__init__.py +0 -1
- mindsdb/integrations/handlers/lancedb_handler/requirements.txt +0 -1
- mindsdb/integrations/handlers/langchain_handler/langchain_handler.py +4 -4
- mindsdb/integrations/handlers/langchain_handler/tools.py +9 -10
- mindsdb/integrations/handlers/leonardoai_handler/__init__.py +1 -1
- mindsdb/integrations/handlers/lightwood_handler/functions.py +2 -2
- mindsdb/integrations/handlers/lightwood_handler/lightwood_handler.py +0 -1
- mindsdb/integrations/handlers/lightwood_handler/tests/test_lightwood_handler.py +11 -11
- mindsdb/integrations/handlers/litellm_handler/litellm_handler.py +37 -20
- mindsdb/integrations/handlers/llama_index_handler/llama_index_handler.py +4 -4
- mindsdb/integrations/handlers/llama_index_handler/settings.py +10 -9
- mindsdb/integrations/handlers/materialize_handler/tests/test_materialize_handler.py +8 -10
- mindsdb/integrations/handlers/matrixone_handler/matrixone_handler.py +4 -4
- mindsdb/integrations/handlers/matrixone_handler/tests/test_matrixone_handler.py +8 -9
- mindsdb/integrations/handlers/maxdb_handler/connection_args.py +25 -25
- mindsdb/integrations/handlers/maxdb_handler/maxdb_handler.py +1 -0
- mindsdb/integrations/handlers/mediawiki_handler/mediawiki_handler.py +3 -2
- mindsdb/integrations/handlers/mediawiki_handler/mediawiki_tables.py +1 -1
- mindsdb/integrations/handlers/mendeley_handler/__about__.py +1 -1
- mindsdb/integrations/handlers/mendeley_handler/__init__.py +2 -2
- mindsdb/integrations/handlers/mendeley_handler/mendeley_handler.py +48 -56
- mindsdb/integrations/handlers/mendeley_handler/mendeley_tables.py +24 -29
- mindsdb/integrations/handlers/mendeley_handler/tests/test_mendeley_handler.py +19 -17
- mindsdb/integrations/handlers/merlion_handler/merlion_handler.py +5 -4
- mindsdb/integrations/handlers/minds_endpoint_handler/__init__.py +3 -3
- mindsdb/integrations/handlers/mlflow_handler/mlflow_handler.py +58 -36
- mindsdb/integrations/handlers/monetdb_handler/__about__.py +8 -8
- mindsdb/integrations/handlers/monetdb_handler/__init__.py +15 -5
- mindsdb/integrations/handlers/monetdb_handler/connection_args.py +17 -18
- mindsdb/integrations/handlers/monetdb_handler/monetdb_handler.py +40 -57
- mindsdb/integrations/handlers/monetdb_handler/tests/test_monetdb_handler.py +7 -8
- mindsdb/integrations/handlers/monetdb_handler/utils/monet_get_id.py +13 -14
- mindsdb/integrations/handlers/monkeylearn_handler/__about__.py +1 -1
- mindsdb/integrations/handlers/monkeylearn_handler/__init__.py +1 -1
- mindsdb/integrations/handlers/monkeylearn_handler/monkeylearn_handler.py +2 -5
- mindsdb/integrations/handlers/ms_one_drive_handler/ms_graph_api_one_drive_client.py +1 -0
- mindsdb/integrations/handlers/ms_one_drive_handler/ms_one_drive_handler.py +1 -1
- mindsdb/integrations/handlers/ms_teams_handler/ms_graph_api_teams_client.py +23 -23
- mindsdb/integrations/handlers/ms_teams_handler/ms_teams_handler.py +3 -3
- mindsdb/integrations/handlers/ms_teams_handler/ms_teams_tables.py +10 -5
- mindsdb/integrations/handlers/mssql_handler/mssql_handler.py +73 -8
- mindsdb/integrations/handlers/mysql_handler/__about__.py +8 -8
- mindsdb/integrations/handlers/mysql_handler/__init__.py +15 -5
- mindsdb/integrations/handlers/mysql_handler/connection_args.py +43 -47
- mindsdb/integrations/handlers/mysql_handler/mysql_handler.py +101 -34
- mindsdb/integrations/handlers/mysql_handler/settings.py +15 -13
- mindsdb/integrations/handlers/neuralforecast_handler/neuralforecast_handler.py +1 -1
- mindsdb/integrations/handlers/newsapi_handler/newsapi_handler.py +1 -1
- mindsdb/integrations/handlers/newsapi_handler/tests/test_newsapi_handler.py +4 -4
- mindsdb/integrations/handlers/nuo_jdbc_handler/connection_args.py +2 -2
- mindsdb/integrations/handlers/nuo_jdbc_handler/nuo_jdbc_handler.py +28 -36
- mindsdb/integrations/handlers/nuo_jdbc_handler/tests/test_nuo_handler.py +5 -5
- mindsdb/integrations/handlers/oceanbase_handler/oceanbase_handler.py +0 -1
- mindsdb/integrations/handlers/oceanbase_handler/tests/test_oceanbase_handler.py +8 -10
- mindsdb/integrations/handlers/ollama_handler/ollama_handler.py +3 -3
- mindsdb/integrations/handlers/opengauss_handler/tests/test_opengauss_handler.py +1 -2
- mindsdb/integrations/handlers/openstreetmap_handler/__init__.py +7 -7
- mindsdb/integrations/handlers/oracle_handler/connection_args.py +6 -0
- mindsdb/integrations/handlers/oracle_handler/oracle_handler.py +77 -11
- mindsdb/integrations/handlers/orioledb_handler/tests/test_orioledb_handler.py +8 -10
- mindsdb/integrations/handlers/palm_handler/__about__.py +1 -1
- mindsdb/integrations/handlers/palm_handler/__init__.py +1 -1
- mindsdb/integrations/handlers/palm_handler/palm_handler.py +1 -3
- mindsdb/integrations/handlers/paypal_handler/paypal_handler.py +2 -2
- mindsdb/integrations/handlers/paypal_handler/paypal_tables.py +15 -14
- mindsdb/integrations/handlers/pgvector_handler/pgvector_handler.py +53 -10
- mindsdb/integrations/handlers/phoenix_handler/__init__.py +1 -1
- mindsdb/integrations/handlers/phoenix_handler/phoenix_handler.py +1 -0
- mindsdb/integrations/handlers/pinot_handler/__init__.py +1 -1
- mindsdb/integrations/handlers/pinot_handler/pinot_handler.py +3 -2
- mindsdb/integrations/handlers/plaid_handler/plaid_handler.py +13 -13
- mindsdb/integrations/handlers/plaid_handler/plaid_tables.py +10 -12
- mindsdb/integrations/handlers/plaid_handler/utils.py +4 -6
- mindsdb/integrations/handlers/planetscale_handler/planetscale_handler.py +1 -4
- mindsdb/integrations/handlers/portkey_handler/__init__.py +2 -2
- mindsdb/integrations/handlers/postgres_handler/postgres_handler.py +105 -24
- mindsdb/integrations/handlers/postgres_handler/tests/test_postgres_handler.py +11 -6
- mindsdb/integrations/handlers/questdb_handler/questdb_handler.py +1 -2
- mindsdb/integrations/handlers/questdb_handler/tests/test_questdb_handler.py +2 -3
- mindsdb/integrations/handlers/quickbooks_handler/quickbooks_handler.py +6 -8
- mindsdb/integrations/handlers/quickbooks_handler/quickbooks_table.py +10 -10
- mindsdb/integrations/handlers/rag_handler/ingest.py +2 -2
- mindsdb/integrations/handlers/rag_handler/rag_handler.py +1 -1
- mindsdb/integrations/handlers/rag_handler/settings.py +1 -1
- mindsdb/integrations/handlers/reddit_handler/reddit_handler.py +2 -7
- mindsdb/integrations/handlers/reddit_handler/reddit_tables.py +2 -3
- mindsdb/integrations/handlers/replicate_handler/replicate_handler.py +6 -6
- mindsdb/integrations/handlers/rocket_chat_handler/rocket_chat_handler.py +1 -2
- mindsdb/integrations/handlers/rocket_chat_handler/rocket_chat_tables.py +0 -3
- mindsdb/integrations/handlers/rockset_handler/connection_args.py +14 -14
- mindsdb/integrations/handlers/rockset_handler/tests/test_rockset_handler.py +1 -0
- mindsdb/integrations/handlers/scylla_handler/scylla_handler.py +6 -5
- mindsdb/integrations/handlers/sendinblue_handler/sendinblue_handler.py +2 -1
- mindsdb/integrations/handlers/sendinblue_handler/sendinblue_tables.py +16 -16
- mindsdb/integrations/handlers/sentence_transformers_handler/__init__.py +1 -1
- mindsdb/integrations/handlers/sheets_handler/connection_args.py +1 -1
- mindsdb/integrations/handlers/shopify_handler/shopify_handler.py +7 -6
- mindsdb/integrations/handlers/shopify_handler/shopify_tables.py +38 -41
- mindsdb/integrations/handlers/singlestore_handler/__about__.py +1 -1
- mindsdb/integrations/handlers/singlestore_handler/__init__.py +0 -1
- mindsdb/integrations/handlers/singlestore_handler/singlestore_handler.py +1 -0
- mindsdb/integrations/handlers/singlestore_handler/tests/test_singlestore_handler.py +3 -3
- mindsdb/integrations/handlers/slack_handler/__init__.py +3 -3
- mindsdb/integrations/handlers/snowflake_handler/snowflake_handler.py +100 -6
- mindsdb/integrations/handlers/solr_handler/connection_args.py +7 -7
- mindsdb/integrations/handlers/solr_handler/solr_handler.py +2 -1
- mindsdb/integrations/handlers/solr_handler/tests/test_solr_handler.py +2 -1
- mindsdb/integrations/handlers/sqlany_handler/sqlany_handler.py +3 -2
- mindsdb/integrations/handlers/sqlite_handler/sqlite_handler.py +1 -0
- mindsdb/integrations/handlers/sqreamdb_handler/connection_args.py +1 -1
- mindsdb/integrations/handlers/sqreamdb_handler/sqreamdb_handler.py +15 -20
- mindsdb/integrations/handlers/sqreamdb_handler/tests/test_sqreamdb_handler.py +4 -4
- mindsdb/integrations/handlers/stabilityai_handler/__init__.py +1 -1
- mindsdb/integrations/handlers/starrocks_handler/starrocks_handler.py +0 -1
- mindsdb/integrations/handlers/starrocks_handler/tests/test_starrocks_handler.py +8 -10
- mindsdb/integrations/handlers/statsforecast_handler/statsforecast_handler.py +2 -2
- mindsdb/integrations/handlers/strava_handler/strava_handler.py +4 -8
- mindsdb/integrations/handlers/strava_handler/strava_tables.py +22 -30
- mindsdb/integrations/handlers/stripe_handler/stripe_handler.py +3 -2
- mindsdb/integrations/handlers/stripe_handler/stripe_tables.py +11 -27
- mindsdb/integrations/handlers/supabase_handler/tests/test_supabase_handler.py +1 -1
- mindsdb/integrations/handlers/surrealdb_handler/surrealdb_handler.py +4 -4
- mindsdb/integrations/handlers/tdengine_handler/tdengine_handler.py +25 -27
- mindsdb/integrations/handlers/tdengine_handler/tests/test_tdengine_handler.py +8 -8
- mindsdb/integrations/handlers/tidb_handler/tests/test_tidb_handler.py +1 -2
- mindsdb/integrations/handlers/timegpt_handler/timegpt_handler.py +5 -5
- mindsdb/integrations/handlers/tpot_handler/tpot_handler.py +21 -26
- mindsdb/integrations/handlers/trino_handler/trino_handler.py +14 -14
- mindsdb/integrations/handlers/twitter_handler/twitter_handler.py +2 -4
- mindsdb/integrations/handlers/unify_handler/tests/test_unify_handler.py +7 -8
- mindsdb/integrations/handlers/unify_handler/unify_handler.py +9 -9
- mindsdb/integrations/handlers/vertex_handler/vertex_client.py +1 -1
- mindsdb/integrations/handlers/vertica_handler/tests/test_vertica_handler.py +11 -11
- mindsdb/integrations/handlers/vertica_handler/vertica_handler.py +11 -14
- mindsdb/integrations/handlers/vitess_handler/tests/test_vitess_handler.py +9 -11
- mindsdb/integrations/handlers/vitess_handler/vitess_handler.py +0 -1
- mindsdb/integrations/handlers/web_handler/web_handler.py +1 -0
- mindsdb/integrations/handlers/whatsapp_handler/__init__.py +3 -3
- mindsdb/integrations/handlers/writer_handler/evaluate.py +1 -1
- mindsdb/integrations/handlers/writer_handler/settings.py +0 -1
- mindsdb/integrations/handlers/writer_handler/writer_handler.py +1 -0
- mindsdb/integrations/handlers/youtube_handler/youtube_handler.py +5 -5
- mindsdb/integrations/handlers/youtube_handler/youtube_tables.py +26 -27
- mindsdb/integrations/handlers/yugabyte_handler/tests/test_yugabyte_handler.py +3 -3
- mindsdb/integrations/handlers/yugabyte_handler/yugabyte_handler.py +0 -6
- mindsdb/integrations/libs/llm/config.py +13 -0
- mindsdb/integrations/libs/llm/utils.py +37 -65
- mindsdb/integrations/libs/response.py +67 -52
- mindsdb/integrations/libs/vectordatabase_handler.py +6 -0
- mindsdb/integrations/utilities/handler_utils.py +15 -3
- mindsdb/integrations/utilities/handlers/api_utilities/__init__.py +0 -1
- mindsdb/integrations/utilities/handlers/auth_utilities/__init__.py +0 -2
- mindsdb/integrations/utilities/rag/rerankers/base_reranker.py +230 -227
- mindsdb/integrations/utilities/utils.py +3 -3
- mindsdb/interfaces/agents/agents_controller.py +164 -1
- mindsdb/interfaces/agents/constants.py +32 -13
- mindsdb/interfaces/agents/langchain_agent.py +106 -95
- mindsdb/interfaces/agents/mindsdb_database_agent.py +101 -2
- mindsdb/interfaces/knowledge_base/controller.py +250 -216
- mindsdb/interfaces/knowledge_base/preprocessing/document_preprocessor.py +13 -10
- mindsdb/interfaces/knowledge_base/preprocessing/json_chunker.py +434 -0
- mindsdb/interfaces/knowledge_base/preprocessing/models.py +54 -0
- mindsdb/interfaces/query_context/context_controller.py +66 -10
- mindsdb/interfaces/skills/custom/text2sql/mindsdb_kb_tools.py +190 -0
- mindsdb/interfaces/skills/custom/text2sql/mindsdb_sql_toolkit.py +92 -0
- mindsdb/interfaces/skills/skill_tool.py +202 -57
- mindsdb/interfaces/skills/sql_agent.py +205 -17
- mindsdb/interfaces/storage/fs.py +1 -0
- mindsdb/interfaces/variables/__init__.py +0 -0
- mindsdb/interfaces/variables/variables_controller.py +97 -0
- mindsdb/migrations/env.py +5 -7
- mindsdb/migrations/migrate.py +47 -7
- mindsdb/migrations/versions/2025-05-21_9f150e4f9a05_checkpoint_1.py +360 -0
- mindsdb/utilities/config.py +287 -216
- mindsdb/utilities/starters.py +13 -0
- {mindsdb-25.5.3.0.dist-info → mindsdb-25.5.4.1.dist-info}/METADATA +646 -698
- {mindsdb-25.5.3.0.dist-info → mindsdb-25.5.4.1.dist-info}/RECORD +312 -295
- {mindsdb-25.5.3.0.dist-info → mindsdb-25.5.4.1.dist-info}/WHEEL +1 -1
- mindsdb/integrations/handlers/monkeylearn_handler/requirements.txt +0 -1
- {mindsdb-25.5.3.0.dist-info → mindsdb-25.5.4.1.dist-info}/licenses/LICENSE +0 -0
- {mindsdb-25.5.3.0.dist-info → mindsdb-25.5.4.1.dist-info}/top_level.txt +0 -0
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
from dataclasses import dataclass, field
|
|
2
|
-
from typing import
|
|
2
|
+
from typing import List, Dict
|
|
3
3
|
|
|
4
4
|
import pandas as pd
|
|
5
5
|
|
|
6
|
+
from mindsdb.api.mysql.mysql_proxy.libs.constants.mysql import MYSQL_DATA_TYPE
|
|
7
|
+
|
|
6
8
|
|
|
7
9
|
@dataclass
|
|
8
10
|
class DataHubResponse:
|
|
9
11
|
data_frame: pd.DataFrame = field(default_factory=pd.DataFrame)
|
|
10
12
|
columns: List[Dict] = field(default_factory=list)
|
|
11
|
-
affected_rows:
|
|
13
|
+
affected_rows: int | None = None
|
|
14
|
+
mysql_types: list[MYSQL_DATA_TYPE] | None = None
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import time
|
|
2
2
|
import inspect
|
|
3
3
|
from dataclasses import astuple
|
|
4
|
+
from typing import Iterable
|
|
4
5
|
|
|
5
6
|
import numpy as np
|
|
6
|
-
from numpy import dtype as np_dtype
|
|
7
7
|
import pandas as pd
|
|
8
|
-
from pandas.api import types as pd_types
|
|
9
8
|
from sqlalchemy.types import (
|
|
10
|
-
Integer, Float
|
|
9
|
+
Integer, Float
|
|
11
10
|
)
|
|
12
11
|
|
|
13
12
|
from mindsdb_sql_parser.ast.base import ASTNode
|
|
@@ -121,9 +120,7 @@ class IntegrationDataNode(DataNode):
|
|
|
121
120
|
tables=[name],
|
|
122
121
|
if_exists=if_exists
|
|
123
122
|
)
|
|
124
|
-
|
|
125
|
-
if result.type == RESPONSE_TYPE.ERROR:
|
|
126
|
-
raise Exception(result.error_message)
|
|
123
|
+
self.query(drop_ast)
|
|
127
124
|
|
|
128
125
|
def create_table(self, table_name: Identifier, result_set: ResultSet = None, columns=None,
|
|
129
126
|
is_replace=False, is_create=False, **kwargs) -> DataHubResponse:
|
|
@@ -138,27 +135,11 @@ class IntegrationDataNode(DataNode):
|
|
|
138
135
|
|
|
139
136
|
df = result_set.get_raw_df()
|
|
140
137
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
if pd_types.is_object_dtype(dtype):
|
|
147
|
-
# try to infer
|
|
148
|
-
dtype = df[idx].infer_objects().dtype
|
|
149
|
-
|
|
150
|
-
if pd_types.is_integer_dtype(dtype):
|
|
151
|
-
column_type = Integer
|
|
152
|
-
elif pd_types.is_numeric_dtype(dtype):
|
|
153
|
-
column_type = Float
|
|
154
|
-
|
|
155
|
-
columns.append(
|
|
156
|
-
TableColumn(
|
|
157
|
-
name=col.alias,
|
|
158
|
-
type=column_type
|
|
159
|
-
)
|
|
160
|
-
)
|
|
161
|
-
table_columns_meta[col.alias] = column_type
|
|
138
|
+
columns: list[TableColumn] = result_set.get_ast_columns()
|
|
139
|
+
table_columns_meta = {
|
|
140
|
+
column.name: column.type
|
|
141
|
+
for column in columns
|
|
142
|
+
}
|
|
162
143
|
|
|
163
144
|
if is_replace:
|
|
164
145
|
# drop
|
|
@@ -166,9 +147,7 @@ class IntegrationDataNode(DataNode):
|
|
|
166
147
|
tables=[table_name],
|
|
167
148
|
if_exists=True
|
|
168
149
|
)
|
|
169
|
-
|
|
170
|
-
if result.type == RESPONSE_TYPE.ERROR:
|
|
171
|
-
raise Exception(result.error_message)
|
|
150
|
+
self.query(drop_ast)
|
|
172
151
|
is_create = True
|
|
173
152
|
|
|
174
153
|
if is_create:
|
|
@@ -177,9 +156,7 @@ class IntegrationDataNode(DataNode):
|
|
|
177
156
|
columns=columns,
|
|
178
157
|
is_replace=is_replace
|
|
179
158
|
)
|
|
180
|
-
|
|
181
|
-
if result.type == RESPONSE_TYPE.ERROR:
|
|
182
|
-
raise Exception(result.error_message)
|
|
159
|
+
self.query(create_table_ast)
|
|
183
160
|
|
|
184
161
|
if result_set is None:
|
|
185
162
|
# it is just a 'create table'
|
|
@@ -224,56 +201,44 @@ class IntegrationDataNode(DataNode):
|
|
|
224
201
|
)
|
|
225
202
|
|
|
226
203
|
try:
|
|
227
|
-
result = self.
|
|
204
|
+
result: DataHubResponse = self.query(insert_ast)
|
|
228
205
|
except Exception as e:
|
|
229
206
|
msg = f'[{self.ds_type}/{self.integration_name}]: {str(e)}'
|
|
230
207
|
raise DBHandlerException(msg) from e
|
|
231
208
|
|
|
232
|
-
if result.type == RESPONSE_TYPE.ERROR:
|
|
233
|
-
raise Exception(result.error_message)
|
|
234
|
-
|
|
235
209
|
return DataHubResponse(affected_rows=result.affected_rows)
|
|
236
210
|
|
|
237
|
-
def
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
num_rows = 0
|
|
246
|
-
if result.data_frame is not None:
|
|
247
|
-
num_rows = len(result.data_frame.index)
|
|
248
|
-
response_size_with_labels = metrics.INTEGRATION_HANDLER_RESPONSE_SIZE.labels(
|
|
249
|
-
get_class_name(self.integration_handler), result.type)
|
|
250
|
-
response_size_with_labels.observe(num_rows)
|
|
251
|
-
return result
|
|
252
|
-
|
|
253
|
-
def _native_query(self, native_query) -> HandlerResponse:
|
|
254
|
-
time_before_query = time.perf_counter()
|
|
255
|
-
result = self.integration_handler.native_query(native_query)
|
|
256
|
-
elapsed_seconds = time.perf_counter() - time_before_query
|
|
257
|
-
query_time_with_labels = metrics.INTEGRATION_HANDLER_QUERY_TIME.labels(
|
|
258
|
-
get_class_name(self.integration_handler), result.type)
|
|
259
|
-
query_time_with_labels.observe(elapsed_seconds)
|
|
260
|
-
|
|
261
|
-
num_rows = 0
|
|
262
|
-
if result.data_frame is not None:
|
|
263
|
-
num_rows = len(result.data_frame.index)
|
|
264
|
-
response_size_with_labels = metrics.INTEGRATION_HANDLER_RESPONSE_SIZE.labels(
|
|
265
|
-
get_class_name(self.integration_handler), result.type)
|
|
266
|
-
response_size_with_labels.observe(num_rows)
|
|
267
|
-
return result
|
|
211
|
+
def has_support_stream(self) -> bool:
|
|
212
|
+
# checks if data handler has query_stream method
|
|
213
|
+
return hasattr(self.integration_handler, 'query_stream') and callable(self.integration_handler.query_stream)
|
|
214
|
+
|
|
215
|
+
@profiler.profile()
|
|
216
|
+
def query_stream(self, query: ASTNode, fetch_size: int = None) -> Iterable:
|
|
217
|
+
# returns generator of results from handler (split by chunks)
|
|
218
|
+
return self.integration_handler.query_stream(query, fetch_size=fetch_size)
|
|
268
219
|
|
|
269
220
|
@profiler.profile()
|
|
270
221
|
def query(self, query: ASTNode | None = None, native_query: str | None = None, session=None) -> DataHubResponse:
|
|
271
222
|
try:
|
|
223
|
+
time_before_query = time.perf_counter()
|
|
272
224
|
if query is not None:
|
|
273
|
-
result: HandlerResponse = self.
|
|
225
|
+
result: HandlerResponse = self.integration_handler.query(query)
|
|
274
226
|
else:
|
|
275
227
|
# try to fetch native query
|
|
276
|
-
result: HandlerResponse = self.
|
|
228
|
+
result: HandlerResponse = self.integration_handler.native_query(native_query)
|
|
229
|
+
|
|
230
|
+
# metrics
|
|
231
|
+
elapsed_seconds = time.perf_counter() - time_before_query
|
|
232
|
+
query_time_with_labels = metrics.INTEGRATION_HANDLER_QUERY_TIME.labels(
|
|
233
|
+
get_class_name(self.integration_handler), result.type)
|
|
234
|
+
query_time_with_labels.observe(elapsed_seconds)
|
|
235
|
+
|
|
236
|
+
num_rows = 0
|
|
237
|
+
if result.data_frame is not None:
|
|
238
|
+
num_rows = len(result.data_frame.index)
|
|
239
|
+
response_size_with_labels = metrics.INTEGRATION_HANDLER_RESPONSE_SIZE.labels(
|
|
240
|
+
get_class_name(self.integration_handler), result.type)
|
|
241
|
+
response_size_with_labels.observe(num_rows)
|
|
277
242
|
except Exception as e:
|
|
278
243
|
msg = str(e).strip()
|
|
279
244
|
if msg == '':
|
|
@@ -294,7 +259,8 @@ class IntegrationDataNode(DataNode):
|
|
|
294
259
|
|
|
295
260
|
try:
|
|
296
261
|
# replace python's Nan, np.NaN, np.nan and pd.NA to None
|
|
297
|
-
|
|
262
|
+
# TODO keep all NAN to the end of processing, bacause replacing also changes dtypes
|
|
263
|
+
df.replace([np.NaN, pd.NA, pd.NaT], None, inplace=True)
|
|
298
264
|
except Exception as e:
|
|
299
265
|
logger.error(f"Issue with clearing DF from NaN values: {e}")
|
|
300
266
|
# endregion
|
|
@@ -310,5 +276,6 @@ class IntegrationDataNode(DataNode):
|
|
|
310
276
|
return DataHubResponse(
|
|
311
277
|
data_frame=df,
|
|
312
278
|
columns=columns_info,
|
|
313
|
-
affected_rows=result.affected_rows
|
|
279
|
+
affected_rows=result.affected_rows,
|
|
280
|
+
mysql_types=result.mysql_types
|
|
314
281
|
)
|
|
@@ -848,11 +848,12 @@ class QueryPlanner:
|
|
|
848
848
|
"""
|
|
849
849
|
|
|
850
850
|
# handle fetchdataframe partitioning
|
|
851
|
+
steps_in = plan.steps
|
|
851
852
|
steps_out = []
|
|
852
853
|
|
|
853
854
|
step = None
|
|
854
855
|
partition_step = None
|
|
855
|
-
for step in
|
|
856
|
+
for step in steps_in:
|
|
856
857
|
if isinstance(step, FetchDataframeStep) and step.params is not None:
|
|
857
858
|
batch_size = step.params.get('batch_size')
|
|
858
859
|
if batch_size is not None:
|
|
@@ -905,6 +906,14 @@ class QueryPlanner:
|
|
|
905
906
|
|
|
906
907
|
if plan.is_resumable and isinstance(step, InsertToTable):
|
|
907
908
|
plan.is_async = True
|
|
909
|
+
else:
|
|
910
|
+
# special case: register insert from select (it is the same as mark resumable)
|
|
911
|
+
if (
|
|
912
|
+
len(steps_in) == 2
|
|
913
|
+
and isinstance(steps_in[0], FetchDataframeStep)
|
|
914
|
+
and isinstance(steps_in[1], InsertToTable)
|
|
915
|
+
):
|
|
916
|
+
plan.is_resumable = True
|
|
908
917
|
|
|
909
918
|
plan.steps = steps_out
|
|
910
919
|
return plan
|
|
@@ -1,29 +1,70 @@
|
|
|
1
1
|
import copy
|
|
2
|
-
from
|
|
2
|
+
from dataclasses import dataclass, field, MISSING
|
|
3
3
|
|
|
4
4
|
import numpy as np
|
|
5
5
|
import pandas as pd
|
|
6
|
+
from pandas.api import types as pd_types
|
|
7
|
+
import sqlalchemy.types as sqlalchemy_types
|
|
6
8
|
|
|
9
|
+
from mindsdb_sql_parser.ast import TableColumn
|
|
10
|
+
|
|
11
|
+
from mindsdb.utilities import log
|
|
7
12
|
from mindsdb.api.executor.exceptions import WrongArgumentError
|
|
13
|
+
from mindsdb.api.mysql.mysql_proxy.libs.constants.mysql import MYSQL_DATA_TYPE
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
logger = log.getLogger(__name__)
|
|
17
|
+
|
|
8
18
|
|
|
19
|
+
def get_mysql_data_type_from_series(series: pd.Series, do_infer: bool = False) -> MYSQL_DATA_TYPE:
|
|
20
|
+
"""Maps pandas Series data type to corresponding MySQL data type.
|
|
9
21
|
|
|
22
|
+
This function examines the dtype of a pandas Series and returns the appropriate
|
|
23
|
+
MySQL data type enum value. For object dtypes, it can optionally attempt to infer
|
|
24
|
+
a more specific type.
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
series (pd.Series): The pandas Series to determine the MySQL type for
|
|
28
|
+
do_infer (bool): If True and series has object dtype, attempt to infer a more specific type
|
|
29
|
+
|
|
30
|
+
Returns:
|
|
31
|
+
MYSQL_DATA_TYPE: The corresponding MySQL data type enum value
|
|
32
|
+
"""
|
|
33
|
+
dtype = series.dtype
|
|
34
|
+
if pd_types.is_object_dtype(dtype) and do_infer is True:
|
|
35
|
+
dtype = series.infer_objects().dtype
|
|
36
|
+
|
|
37
|
+
if pd_types.is_object_dtype(dtype):
|
|
38
|
+
return MYSQL_DATA_TYPE.TEXT
|
|
39
|
+
if pd_types.is_datetime64_dtype(dtype):
|
|
40
|
+
return MYSQL_DATA_TYPE.DATETIME
|
|
41
|
+
if pd_types.is_string_dtype(dtype):
|
|
42
|
+
return MYSQL_DATA_TYPE.TEXT
|
|
43
|
+
if pd_types.is_bool_dtype(dtype):
|
|
44
|
+
return MYSQL_DATA_TYPE.BOOL
|
|
45
|
+
if pd_types.is_integer_dtype(dtype):
|
|
46
|
+
return MYSQL_DATA_TYPE.INT
|
|
47
|
+
if pd_types.is_numeric_dtype(dtype):
|
|
48
|
+
return MYSQL_DATA_TYPE.FLOAT
|
|
49
|
+
return MYSQL_DATA_TYPE.TEXT
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@dataclass(kw_only=True, slots=True)
|
|
10
53
|
class Column:
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
self.
|
|
22
|
-
|
|
23
|
-
self.
|
|
24
|
-
|
|
25
|
-
self.flags = flags
|
|
26
|
-
self.charset = charset
|
|
54
|
+
name: str = field(default=MISSING)
|
|
55
|
+
alias: str | None = None
|
|
56
|
+
table_name: str | None = None
|
|
57
|
+
table_alias: str | None = None
|
|
58
|
+
type: MYSQL_DATA_TYPE | None = None
|
|
59
|
+
database: str | None = None
|
|
60
|
+
flags: dict = None
|
|
61
|
+
charset: str | None = None
|
|
62
|
+
|
|
63
|
+
def __post_init__(self):
|
|
64
|
+
if self.alias is None:
|
|
65
|
+
self.alias = self.name
|
|
66
|
+
if self.table_alias is None:
|
|
67
|
+
self.table_alias = self.table_name
|
|
27
68
|
|
|
28
69
|
def get_hash_name(self, prefix):
|
|
29
70
|
table_name = self.table_name if self.table_alias is None else self.table_alias
|
|
@@ -32,11 +73,8 @@ class Column:
|
|
|
32
73
|
name = f'{prefix}_{table_name}_{name}'
|
|
33
74
|
return name
|
|
34
75
|
|
|
35
|
-
def __repr__(self):
|
|
36
|
-
return f'{self.__class__.__name__}({self.__dict__})'
|
|
37
|
-
|
|
38
76
|
|
|
39
|
-
def rename_df_columns(df: pd.DataFrame, names:
|
|
77
|
+
def rename_df_columns(df: pd.DataFrame, names: list | None = None) -> None:
|
|
40
78
|
"""Inplace rename of dataframe columns
|
|
41
79
|
|
|
42
80
|
Args:
|
|
@@ -50,7 +88,15 @@ def rename_df_columns(df: pd.DataFrame, names: Optional[List] = None) -> None:
|
|
|
50
88
|
|
|
51
89
|
|
|
52
90
|
class ResultSet:
|
|
53
|
-
def __init__(
|
|
91
|
+
def __init__(
|
|
92
|
+
self,
|
|
93
|
+
columns: list[Column] | None = None,
|
|
94
|
+
values: list[list] | None = None,
|
|
95
|
+
df: pd.DataFrame | None = None,
|
|
96
|
+
affected_rows: int | None = None,
|
|
97
|
+
is_prediction: bool = False,
|
|
98
|
+
mysql_types: list[MYSQL_DATA_TYPE] | None = None
|
|
99
|
+
):
|
|
54
100
|
"""
|
|
55
101
|
Args:
|
|
56
102
|
columns: list of Columns
|
|
@@ -62,15 +108,18 @@ class ResultSet:
|
|
|
62
108
|
columns = []
|
|
63
109
|
self._columns = columns
|
|
64
110
|
|
|
65
|
-
if
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
111
|
+
if df is None:
|
|
112
|
+
if values is None:
|
|
113
|
+
df = None
|
|
114
|
+
else:
|
|
115
|
+
df = pd.DataFrame(values)
|
|
69
116
|
self._df = df
|
|
70
117
|
|
|
71
118
|
self.affected_rows = affected_rows
|
|
72
119
|
|
|
73
|
-
self.is_prediction =
|
|
120
|
+
self.is_prediction = is_prediction
|
|
121
|
+
|
|
122
|
+
self.mysql_types = mysql_types
|
|
74
123
|
|
|
75
124
|
def __repr__(self):
|
|
76
125
|
col_names = ', '.join([col.name for col in self._columns])
|
|
@@ -89,43 +138,76 @@ class ResultSet:
|
|
|
89
138
|
|
|
90
139
|
# --- converters ---
|
|
91
140
|
|
|
92
|
-
|
|
93
|
-
|
|
141
|
+
@classmethod
|
|
142
|
+
def from_df(
|
|
143
|
+
cls, df: pd.DataFrame, database=None, table_name=None, table_alias=None,
|
|
144
|
+
is_prediction: bool = False, mysql_types: list[MYSQL_DATA_TYPE] | None = None
|
|
145
|
+
):
|
|
146
|
+
match mysql_types:
|
|
147
|
+
case None:
|
|
148
|
+
mysql_types = [None] * len(df.columns)
|
|
149
|
+
case list() if len(mysql_types) != len(df.columns):
|
|
150
|
+
raise WrongArgumentError(
|
|
151
|
+
f'Mysql types length mismatch: {len(mysql_types)} != {len(df.columns)}'
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
columns = [
|
|
94
155
|
Column(
|
|
95
156
|
name=column_name,
|
|
96
157
|
table_name=table_name,
|
|
97
158
|
table_alias=table_alias,
|
|
98
159
|
database=database,
|
|
99
|
-
type=
|
|
100
|
-
) for column_name,
|
|
101
|
-
in zip(df.columns,
|
|
160
|
+
type=mysql_type
|
|
161
|
+
) for column_name, mysql_type
|
|
162
|
+
in zip(df.columns, mysql_types)
|
|
102
163
|
]
|
|
103
164
|
|
|
104
165
|
rename_df_columns(df)
|
|
105
|
-
|
|
166
|
+
return cls(
|
|
167
|
+
df=df,
|
|
168
|
+
columns=columns,
|
|
169
|
+
is_prediction=is_prediction,
|
|
170
|
+
mysql_types=mysql_types
|
|
171
|
+
)
|
|
106
172
|
|
|
107
|
-
|
|
173
|
+
@classmethod
|
|
174
|
+
def from_df_cols(cls, df: pd.DataFrame, columns_dict: dict[str, Column], strict: bool = True) -> 'ResultSet':
|
|
175
|
+
"""Create ResultSet from dataframe and dictionary of columns
|
|
108
176
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
if col.alias is not None:
|
|
114
|
-
alias_idx[col.alias] = col
|
|
177
|
+
Args:
|
|
178
|
+
df (pd.DataFrame): dataframe
|
|
179
|
+
columns_dict (dict[str, Column]): dictionary of columns
|
|
180
|
+
strict (bool): if True, raise an error if a column is not found in columns_dict
|
|
115
181
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
182
|
+
Returns:
|
|
183
|
+
ResultSet: result set
|
|
184
|
+
|
|
185
|
+
Raises:
|
|
186
|
+
ValueError: if a column is not found in columns_dict and strict is True
|
|
187
|
+
"""
|
|
188
|
+
alias_idx = {
|
|
189
|
+
column.alias: column
|
|
190
|
+
for column in columns_dict.values()
|
|
191
|
+
if column.alias is not None
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
columns = []
|
|
195
|
+
for column_name in df.columns:
|
|
196
|
+
if strict and column_name not in columns_dict:
|
|
197
|
+
raise ValueError(f'Column {column_name} not found in columns_dict')
|
|
198
|
+
column = (
|
|
199
|
+
columns_dict.get(column_name)
|
|
200
|
+
or alias_idx.get(column_name)
|
|
201
|
+
or Column(name=column_name)
|
|
202
|
+
)
|
|
203
|
+
columns.append(column)
|
|
124
204
|
|
|
125
205
|
rename_df_columns(df)
|
|
126
|
-
self._df = df
|
|
127
206
|
|
|
128
|
-
return
|
|
207
|
+
return cls(
|
|
208
|
+
columns=columns,
|
|
209
|
+
df=df
|
|
210
|
+
)
|
|
129
211
|
|
|
130
212
|
def to_df(self):
|
|
131
213
|
columns_names = self.get_column_names()
|
|
@@ -133,7 +215,7 @@ class ResultSet:
|
|
|
133
215
|
rename_df_columns(df, columns_names)
|
|
134
216
|
return df
|
|
135
217
|
|
|
136
|
-
def to_df_cols(self, prefix=''):
|
|
218
|
+
def to_df_cols(self, prefix: str = '') -> tuple[pd.DataFrame, dict[str, Column]]:
|
|
137
219
|
# returns dataframe and dict of columns
|
|
138
220
|
# can be restored to ResultSet by from_df_cols method
|
|
139
221
|
|
|
@@ -262,6 +344,57 @@ class ResultSet:
|
|
|
262
344
|
)
|
|
263
345
|
self.add_raw_df(df)
|
|
264
346
|
|
|
347
|
+
def get_ast_columns(self) -> list[TableColumn]:
|
|
348
|
+
"""Converts ResultSet columns to a list of TableColumn objects with SQLAlchemy types.
|
|
349
|
+
|
|
350
|
+
This method processes each column in the ResultSet, determines its MySQL data type
|
|
351
|
+
(inferring it if necessary), and maps it to the appropriate SQLAlchemy type.
|
|
352
|
+
The resulting TableColumn objects most likely will be used in CREATE TABLE statement.
|
|
353
|
+
|
|
354
|
+
Returns:
|
|
355
|
+
list[TableColumn]: A list of TableColumn objects with properly mapped SQLAlchemy types
|
|
356
|
+
"""
|
|
357
|
+
columns: list[TableColumn] = []
|
|
358
|
+
|
|
359
|
+
type_mapping = {
|
|
360
|
+
MYSQL_DATA_TYPE.TINYINT: sqlalchemy_types.INTEGER,
|
|
361
|
+
MYSQL_DATA_TYPE.SMALLINT: sqlalchemy_types.INTEGER,
|
|
362
|
+
MYSQL_DATA_TYPE.MEDIUMINT: sqlalchemy_types.INTEGER,
|
|
363
|
+
MYSQL_DATA_TYPE.INT: sqlalchemy_types.INTEGER,
|
|
364
|
+
MYSQL_DATA_TYPE.BIGINT: sqlalchemy_types.INTEGER,
|
|
365
|
+
MYSQL_DATA_TYPE.YEAR: sqlalchemy_types.INTEGER,
|
|
366
|
+
MYSQL_DATA_TYPE.BOOL: sqlalchemy_types.BOOLEAN,
|
|
367
|
+
MYSQL_DATA_TYPE.BOOLEAN: sqlalchemy_types.BOOLEAN,
|
|
368
|
+
MYSQL_DATA_TYPE.FLOAT: sqlalchemy_types.FLOAT,
|
|
369
|
+
MYSQL_DATA_TYPE.DOUBLE: sqlalchemy_types.FLOAT,
|
|
370
|
+
MYSQL_DATA_TYPE.TIME: sqlalchemy_types.TIME,
|
|
371
|
+
MYSQL_DATA_TYPE.DATE: sqlalchemy_types.DATE,
|
|
372
|
+
MYSQL_DATA_TYPE.DATETIME: sqlalchemy_types.DATETIME,
|
|
373
|
+
MYSQL_DATA_TYPE.TIMESTAMP: sqlalchemy_types.TIMESTAMP,
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
for i, column in enumerate(self._columns):
|
|
377
|
+
column_type: MYSQL_DATA_TYPE | None = column.type
|
|
378
|
+
|
|
379
|
+
# infer MYSQL_DATA_TYPE if not set
|
|
380
|
+
if isinstance(column_type, MYSQL_DATA_TYPE) is False:
|
|
381
|
+
if column_type is not None:
|
|
382
|
+
logger.warning(f'Unexpected column type: {column_type}')
|
|
383
|
+
if self._df is None:
|
|
384
|
+
column_type = MYSQL_DATA_TYPE.TEXT
|
|
385
|
+
else:
|
|
386
|
+
column_type = get_mysql_data_type_from_series(self._df.iloc[:, i])
|
|
387
|
+
|
|
388
|
+
sqlalchemy_type = type_mapping.get(column_type, sqlalchemy_types.TEXT)
|
|
389
|
+
|
|
390
|
+
columns.append(
|
|
391
|
+
TableColumn(
|
|
392
|
+
name=column.alias,
|
|
393
|
+
type=sqlalchemy_type
|
|
394
|
+
)
|
|
395
|
+
)
|
|
396
|
+
return columns
|
|
397
|
+
|
|
265
398
|
def to_lists(self, json_types=False):
|
|
266
399
|
"""
|
|
267
400
|
:param type_cast: cast numpy types
|
|
@@ -281,7 +414,7 @@ class ResultSet:
|
|
|
281
414
|
return df.to_records(index=False).tolist()
|
|
282
415
|
|
|
283
416
|
# slower but keep timestamp type
|
|
284
|
-
df = self._df.replace({np.nan: None})
|
|
417
|
+
df = self._df.replace({np.nan: None}) # TODO rework
|
|
285
418
|
return df.to_dict('split')['data']
|
|
286
419
|
|
|
287
420
|
def get_column_values(self, col_idx):
|
|
@@ -252,7 +252,7 @@ class SQLQuery:
|
|
|
252
252
|
# return query info
|
|
253
253
|
# columns in upper case
|
|
254
254
|
rec = {k.upper(): v for k, v in self.run_query.get_info().items()}
|
|
255
|
-
self.fetched_data = ResultSet
|
|
255
|
+
self.fetched_data = ResultSet.from_df(pd.DataFrame([rec]))
|
|
256
256
|
self.columns_list = self.fetched_data.columns
|
|
257
257
|
return
|
|
258
258
|
self.run_query.mark_as_run()
|
|
@@ -91,21 +91,18 @@ class ApplyPredictorRowStepCall(ApplyPredictorBaseCall):
|
|
|
91
91
|
|
|
92
92
|
table_name = get_preditor_alias(step, self.context.get('database'))
|
|
93
93
|
|
|
94
|
-
result = ResultSet()
|
|
95
|
-
result.is_prediction = True
|
|
96
94
|
if len(predictions) == 0:
|
|
97
95
|
columns_names = project_datanode.get_table_columns_names(predictor_name)
|
|
98
96
|
predictions = pd.DataFrame([], columns=columns_names)
|
|
99
97
|
|
|
100
|
-
|
|
101
|
-
predictions,
|
|
98
|
+
return ResultSet.from_df(
|
|
99
|
+
df=predictions,
|
|
102
100
|
database=table_name[0],
|
|
103
101
|
table_name=table_name[1],
|
|
104
|
-
table_alias=table_name[2]
|
|
102
|
+
table_alias=table_name[2],
|
|
103
|
+
is_prediction=True
|
|
105
104
|
)
|
|
106
105
|
|
|
107
|
-
return result
|
|
108
|
-
|
|
109
106
|
|
|
110
107
|
class ApplyPredictorStepCall(ApplyPredictorBaseCall):
|
|
111
108
|
|
|
@@ -164,15 +161,14 @@ class ApplyPredictorStepCall(ApplyPredictorBaseCall):
|
|
|
164
161
|
params['force_ts_infer'] = True
|
|
165
162
|
_mdb_forecast_offset = None
|
|
166
163
|
|
|
167
|
-
data.add_column(Column('__mdb_forecast_offset'), _mdb_forecast_offset)
|
|
164
|
+
data.add_column(Column(name='__mdb_forecast_offset'), _mdb_forecast_offset)
|
|
168
165
|
|
|
169
166
|
table_name = get_preditor_alias(step, self.context['database'])
|
|
170
|
-
result = ResultSet()
|
|
171
|
-
result.is_prediction = True
|
|
172
167
|
|
|
173
168
|
project_datanode = self.session.datahub.get(project_name)
|
|
174
169
|
if len(data) == 0:
|
|
175
170
|
columns_names = project_datanode.get_table_columns_names(predictor_name) + ['__mindsdb_row_id']
|
|
171
|
+
result = ResultSet(is_prediction=True)
|
|
176
172
|
for column_name in columns_names:
|
|
177
173
|
result.add_column(Column(
|
|
178
174
|
name=column_name,
|
|
@@ -230,11 +226,12 @@ class ApplyPredictorStepCall(ApplyPredictorBaseCall):
|
|
|
230
226
|
pred_data = self.apply_ts_filter(pred_data, where_data, step, predictor_metadata)
|
|
231
227
|
predictions = pd.DataFrame(pred_data)
|
|
232
228
|
|
|
233
|
-
result.from_df(
|
|
229
|
+
result = ResultSet.from_df(
|
|
234
230
|
predictions,
|
|
235
231
|
database=table_name[0],
|
|
236
232
|
table_name=table_name[1],
|
|
237
|
-
table_alias=table_name[2]
|
|
233
|
+
table_alias=table_name[2],
|
|
234
|
+
is_prediction=True
|
|
238
235
|
)
|
|
239
236
|
|
|
240
237
|
return result
|
|
@@ -7,11 +7,12 @@ from mindsdb_sql_parser.ast import (
|
|
|
7
7
|
BinaryOperation,
|
|
8
8
|
Tuple,
|
|
9
9
|
)
|
|
10
|
-
from mindsdb.api.executor.planner.steps import FetchDataframeStep
|
|
11
|
-
from mindsdb.integrations.utilities.query_traversal import query_traversal
|
|
12
10
|
|
|
11
|
+
from mindsdb.api.executor.planner.steps import FetchDataframeStep
|
|
12
|
+
from mindsdb.api.executor.datahub.classes.response import DataHubResponse
|
|
13
13
|
from mindsdb.api.executor.sql_query.result_set import ResultSet
|
|
14
14
|
from mindsdb.api.executor.exceptions import UnknownError
|
|
15
|
+
from mindsdb.integrations.utilities.query_traversal import query_traversal
|
|
15
16
|
from mindsdb.interfaces.query_context.context_controller import query_context_controller
|
|
16
17
|
|
|
17
18
|
from .base import BaseStepCall
|
|
@@ -89,7 +90,7 @@ class FetchDataframeStepCall(BaseStepCall):
|
|
|
89
90
|
table_alias = (self.context.get('database'), 'result', 'result')
|
|
90
91
|
|
|
91
92
|
# fetch raw_query
|
|
92
|
-
response = dn.query(
|
|
93
|
+
response: DataHubResponse = dn.query(
|
|
93
94
|
native_query=step.raw_query,
|
|
94
95
|
session=self.session
|
|
95
96
|
)
|
|
@@ -105,7 +106,7 @@ class FetchDataframeStepCall(BaseStepCall):
|
|
|
105
106
|
|
|
106
107
|
query, context_callback = query_context_controller.handle_db_context_vars(query, dn, self.session)
|
|
107
108
|
|
|
108
|
-
response = dn.query(
|
|
109
|
+
response: DataHubResponse = dn.query(
|
|
109
110
|
query=query,
|
|
110
111
|
session=self.session
|
|
111
112
|
)
|
|
@@ -114,13 +115,10 @@ class FetchDataframeStepCall(BaseStepCall):
|
|
|
114
115
|
if context_callback:
|
|
115
116
|
context_callback(df, response.columns)
|
|
116
117
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
result.from_df(
|
|
118
|
+
return ResultSet.from_df(
|
|
120
119
|
df,
|
|
121
120
|
table_name=table_alias[1],
|
|
122
121
|
table_alias=table_alias[2],
|
|
123
|
-
database=table_alias[0]
|
|
122
|
+
database=table_alias[0],
|
|
123
|
+
mysql_types=response.mysql_types
|
|
124
124
|
)
|
|
125
|
-
|
|
126
|
-
return result
|