MindsDB 25.4.5.0__py3-none-any.whl → 25.5.4.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/__main__.py +215 -185
- mindsdb/api/a2a/__init__.py +0 -0
- mindsdb/api/a2a/__main__.py +114 -0
- mindsdb/api/a2a/a2a_client.py +439 -0
- mindsdb/api/a2a/agent.py +308 -0
- mindsdb/api/a2a/common/__init__.py +0 -0
- mindsdb/api/a2a/common/client/__init__.py +4 -0
- mindsdb/api/a2a/common/client/card_resolver.py +21 -0
- mindsdb/api/a2a/common/client/client.py +86 -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 +129 -0
- mindsdb/api/a2a/task_manager.py +594 -0
- mindsdb/api/executor/command_executor.py +49 -28
- mindsdb/api/executor/datahub/classes/response.py +5 -2
- mindsdb/api/executor/datahub/datanodes/information_schema_datanode.py +8 -0
- mindsdb/api/executor/datahub/datanodes/integration_datanode.py +39 -72
- mindsdb/api/executor/datahub/datanodes/system_tables.py +10 -13
- mindsdb/api/executor/planner/query_planner.py +14 -2
- 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 +11 -13
- 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 +118 -85
- mindsdb/api/http/namespaces/analysis.py +17 -4
- mindsdb/api/http/namespaces/file.py +8 -2
- mindsdb/api/http/namespaces/sql.py +13 -27
- mindsdb/api/http/namespaces/tree.py +1 -1
- mindsdb/api/http/start.py +7 -2
- 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 +86 -123
- mindsdb/api/mysql/mysql_proxy/utilities/dump.py +351 -0
- mindsdb/api/mysql/mysql_proxy/utilities/exceptions.py +0 -4
- mindsdb/api/postgres/postgres_proxy/executor/executor.py +1 -1
- mindsdb/api/postgres/postgres_proxy/postgres_packets/postgres_message_formats.py +2 -2
- 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/requirements.txt +1 -0
- 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/chromadb_handler/requirements.txt +1 -0
- 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/gmail_handler/requirements.txt +1 -0
- mindsdb/integrations/handlers/google_analytics_handler/requirements.txt +2 -1
- 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_books_handler/requirements.txt +1 -1
- 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_calendar_handler/requirements.txt +1 -0
- 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_content_shopping_handler/requirements.txt +1 -1
- 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_fit_handler/requirements.txt +2 -0
- 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/google_search_handler/requirements.txt +1 -1
- 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.archived.py +75 -0
- mindsdb/integrations/handlers/jira_handler/jira_handler.py +113 -38
- mindsdb/integrations/handlers/jira_handler/jira_tables.py +229 -0
- mindsdb/integrations/handlers/jira_handler/requirements.txt +1 -0
- mindsdb/integrations/handlers/kinetica_handler/__init__.py +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/lightfm_handler/requirements.txt +1 -0
- mindsdb/integrations/handlers/lightwood_handler/functions.py +2 -2
- mindsdb/integrations/handlers/lightwood_handler/lightwood_handler.py +0 -3
- mindsdb/integrations/handlers/lightwood_handler/requirements.txt +4 -4
- mindsdb/integrations/handlers/lightwood_handler/tests/test_lightwood_handler.py +11 -11
- mindsdb/integrations/handlers/lindorm_handler/requirements.txt +1 -0
- 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_one_drive_handler/requirements.txt +2 -0
- 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/ms_teams_handler/requirements.txt +3 -1
- 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/openai_handler/openai_handler.py +5 -4
- 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/requirements.txt +1 -1
- 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/requirements.txt +1 -0
- 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/requirements.txt +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/response.py +67 -52
- mindsdb/integrations/libs/vectordatabase_handler.py +6 -0
- mindsdb/integrations/utilities/files/file_reader.py +5 -2
- 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/utils.py +3 -3
- mindsdb/interfaces/agents/agents_controller.py +164 -1
- mindsdb/interfaces/agents/constants.py +29 -2
- mindsdb/interfaces/agents/langchain_agent.py +18 -8
- mindsdb/interfaces/agents/mindsdb_database_agent.py +101 -2
- mindsdb/interfaces/database/projects.py +1 -7
- mindsdb/interfaces/functions/controller.py +11 -14
- mindsdb/interfaces/functions/to_markdown.py +9 -124
- mindsdb/interfaces/knowledge_base/controller.py +47 -19
- mindsdb/interfaces/knowledge_base/preprocessing/document_preprocessor.py +41 -15
- mindsdb/interfaces/knowledge_base/preprocessing/json_chunker.py +434 -0
- mindsdb/interfaces/knowledge_base/preprocessing/models.py +54 -0
- mindsdb/interfaces/knowledge_base/utils.py +10 -15
- mindsdb/interfaces/model/model_controller.py +0 -2
- 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 +238 -28
- 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 -9
- mindsdb/migrations/versions/2025-05-21_9f150e4f9a05_checkpoint_1.py +360 -0
- mindsdb/utilities/config.py +333 -220
- mindsdb/utilities/context.py +1 -1
- mindsdb/utilities/functions.py +0 -36
- mindsdb/utilities/langfuse.py +19 -10
- mindsdb/utilities/otel/__init__.py +9 -193
- mindsdb/utilities/otel/metric_handlers/__init__.py +5 -1
- mindsdb/utilities/otel/prepare.py +198 -0
- mindsdb/utilities/sql.py +83 -0
- mindsdb/utilities/starters.py +13 -0
- {mindsdb-25.4.5.0.dist-info → mindsdb-25.5.4.0.dist-info}/METADATA +351 -338
- {mindsdb-25.4.5.0.dist-info → mindsdb-25.5.4.0.dist-info}/RECORD +348 -322
- {mindsdb-25.4.5.0.dist-info → mindsdb-25.5.4.0.dist-info}/WHEEL +1 -1
- mindsdb/api/mysql/mysql_proxy/classes/sql_statement_parser.py +0 -151
- mindsdb/integrations/handlers/monkeylearn_handler/requirements.txt +0 -1
- {mindsdb-25.4.5.0.dist-info → mindsdb-25.5.4.0.dist-info}/licenses/LICENSE +0 -0
- {mindsdb-25.4.5.0.dist-info → mindsdb-25.5.4.0.dist-info}/top_level.txt +0 -0
|
@@ -104,7 +104,7 @@ class SubscriptionsTable(APITable):
|
|
|
104
104
|
return subscriptions_df
|
|
105
105
|
|
|
106
106
|
def get_columns(self) -> List[Text]:
|
|
107
|
-
return pd.json_normalize(self.get_subscriptions(count
|
|
107
|
+
return pd.json_normalize(self.get_subscriptions(count=1)).columns.tolist()
|
|
108
108
|
|
|
109
109
|
def get_subscriptions(self, **kwargs) -> List[Dict]:
|
|
110
110
|
connection = self.handler.connect()
|
|
@@ -114,6 +114,7 @@ class SubscriptionsTable(APITable):
|
|
|
114
114
|
|
|
115
115
|
class OrdersTable(APITable):
|
|
116
116
|
"""The PayPal Orders Table implementation"""
|
|
117
|
+
|
|
117
118
|
def select(self, query: ast.Select) -> pd.DataFrame:
|
|
118
119
|
"""
|
|
119
120
|
Pulls PayPal Orders data.
|
|
@@ -137,18 +138,18 @@ class OrdersTable(APITable):
|
|
|
137
138
|
)
|
|
138
139
|
selected_columns, where_conditions, order_by_conditions, result_limit = select_statement_parser.parse_query()
|
|
139
140
|
|
|
140
|
-
id=None
|
|
141
|
+
id = None
|
|
141
142
|
subset_where_conditions = []
|
|
142
143
|
for op, arg1, arg2 in where_conditions:
|
|
143
144
|
if arg1 == 'id':
|
|
144
145
|
if op == '=':
|
|
145
|
-
id=arg2
|
|
146
|
+
id = arg2
|
|
146
147
|
else:
|
|
147
148
|
raise NotImplementedError("Only '=' operator is supported for 'ids' column")
|
|
148
149
|
elif arg1 in ['state', 'amount', 'create_time', 'update_time', 'links', 'pending_reason', 'parent_payment']:
|
|
149
150
|
subset_where_conditions.append([op, arg1, arg2])
|
|
150
151
|
|
|
151
|
-
if not id
|
|
152
|
+
if not id:
|
|
152
153
|
raise NotImplementedError("id column is required for this table")
|
|
153
154
|
|
|
154
155
|
orders_df = pd.json_normalize(self.get_orders(id))
|
|
@@ -160,16 +161,17 @@ class OrdersTable(APITable):
|
|
|
160
161
|
)
|
|
161
162
|
orders_df = select_statement_executor.execute_query()
|
|
162
163
|
return orders_df
|
|
164
|
+
|
|
163
165
|
def get_columns(self) -> List[Text]:
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
166
|
+
return ["id",
|
|
167
|
+
"status",
|
|
168
|
+
"intent",
|
|
169
|
+
"purchase_units",
|
|
170
|
+
"links",
|
|
171
|
+
"create_time"]
|
|
170
172
|
|
|
171
173
|
# restore this or similar header list for API 2.0 refactor
|
|
172
|
-
#restore this list when restore paypalsdk api, and retired the request call
|
|
174
|
+
# restore this list when restore paypalsdk api, and retired the request call
|
|
173
175
|
# return ["id",
|
|
174
176
|
# "status",
|
|
175
177
|
# "intent",
|
|
@@ -183,7 +185,7 @@ class OrdersTable(APITable):
|
|
|
183
185
|
# "create_time"]
|
|
184
186
|
|
|
185
187
|
def get_orders(self, id) -> List[Dict]:
|
|
186
|
-
#we can use the paypalrestsdk api to get the order if they refactor their code
|
|
188
|
+
# we can use the paypalrestsdk api to get the order if they refactor their code
|
|
187
189
|
connection = self.handler.connect()
|
|
188
190
|
endpoint = f"v2/checkout/orders/{id}"
|
|
189
191
|
order = connection.get(endpoint)
|
|
@@ -259,7 +261,7 @@ class PayoutsTable(APITable):
|
|
|
259
261
|
"fees_value",
|
|
260
262
|
]
|
|
261
263
|
|
|
262
|
-
def get_payout(self, payout_batch_id:str) -> List[Dict]:
|
|
264
|
+
def get_payout(self, payout_batch_id: str) -> List[Dict]:
|
|
263
265
|
connection = self.handler.connect()
|
|
264
266
|
endpoint = f"v1/payments/payouts/{payout_batch_id}"
|
|
265
267
|
payout = connection.get(endpoint)
|
|
@@ -280,4 +282,3 @@ class PayoutsTable(APITable):
|
|
|
280
282
|
}
|
|
281
283
|
|
|
282
284
|
return [payout_data]
|
|
283
|
-
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import json
|
|
3
|
-
from
|
|
4
|
-
from typing import Dict, List, Union
|
|
3
|
+
from typing import Dict, List, Union, Literal
|
|
5
4
|
from urllib.parse import urlparse
|
|
6
5
|
|
|
7
6
|
import pandas as pd
|
|
@@ -39,7 +38,7 @@ class PgVectorHandler(PostgresHandler, VectorStoreHandler):
|
|
|
39
38
|
self._is_vector_registered = False
|
|
40
39
|
# we get these from the connection args on PostgresHandler parent
|
|
41
40
|
self._is_sparse = self.connection_args.get('is_sparse', False)
|
|
42
|
-
self._vector_size = self.connection_args.get('vector_size', None)
|
|
41
|
+
self._vector_size = self.connection_args.get('vector_size', None)
|
|
43
42
|
|
|
44
43
|
if self._is_sparse:
|
|
45
44
|
if not self._vector_size:
|
|
@@ -67,6 +66,21 @@ class PgVectorHandler(PostgresHandler, VectorStoreHandler):
|
|
|
67
66
|
self.distance_op = distance_op
|
|
68
67
|
self.connect()
|
|
69
68
|
|
|
69
|
+
def get_metric_type(self) -> str:
|
|
70
|
+
"""
|
|
71
|
+
Get the metric type from the distance ops
|
|
72
|
+
|
|
73
|
+
"""
|
|
74
|
+
distance_ops_to_metric_type_map = {
|
|
75
|
+
'<->': 'vector_l2_ops',
|
|
76
|
+
'<#>': 'vector_ip_ops',
|
|
77
|
+
'<=>': 'vector_cosine_ops',
|
|
78
|
+
'<+>': 'vector_l1_ops',
|
|
79
|
+
'<~>': 'bit_hamming_ops',
|
|
80
|
+
'<%>': 'bit_jaccard_ops'
|
|
81
|
+
}
|
|
82
|
+
return distance_ops_to_metric_type_map.get(self.distance_op, 'vector_cosine_ops')
|
|
83
|
+
|
|
70
84
|
def _make_connection_args(self):
|
|
71
85
|
cloud_pgvector_url = os.environ.get('KB_PGVECTOR_URL')
|
|
72
86
|
# if no connection args and shared pg vector defined - use it
|
|
@@ -234,7 +248,6 @@ class PgVectorHandler(PostgresHandler, VectorStoreHandler):
|
|
|
234
248
|
|
|
235
249
|
targets = ', '.join(modified_columns)
|
|
236
250
|
|
|
237
|
-
|
|
238
251
|
if filter_conditions:
|
|
239
252
|
|
|
240
253
|
if embedding_search:
|
|
@@ -255,7 +268,7 @@ class PgVectorHandler(PostgresHandler, VectorStoreHandler):
|
|
|
255
268
|
# Calculate distance as part of the query if needed
|
|
256
269
|
if has_distance:
|
|
257
270
|
targets = f"{targets}, (embeddings {self.distance_op} '{search_vector}') as distance"
|
|
258
|
-
|
|
271
|
+
|
|
259
272
|
return f"SELECT {targets} FROM {table_name} {where_clause} ORDER BY embeddings {self.distance_op} '{search_vector}' ASC {limit_clause} {offset_clause} "
|
|
260
273
|
|
|
261
274
|
else:
|
|
@@ -304,7 +317,7 @@ class PgVectorHandler(PostgresHandler, VectorStoreHandler):
|
|
|
304
317
|
embeddings: List[float],
|
|
305
318
|
query: str = None,
|
|
306
319
|
metadata: Dict[str, str] = None,
|
|
307
|
-
distance_function
|
|
320
|
+
distance_function=DistanceFunction.COSINE_DISTANCE,
|
|
308
321
|
**kwargs
|
|
309
322
|
) -> pd.DataFrame:
|
|
310
323
|
'''
|
|
@@ -348,7 +361,7 @@ class PgVectorHandler(PostgresHandler, VectorStoreHandler):
|
|
|
348
361
|
# See https://docs.pgvecto.rs/use-case/hybrid-search.html#advanced-search-merge-the-results-of-full-text-search-and-vector-search.
|
|
349
362
|
#
|
|
350
363
|
# We can break down the below query as follows:
|
|
351
|
-
#
|
|
364
|
+
#
|
|
352
365
|
# Start with a CTE (Common Table Expression) called semantic_search (https://www.postgresql.org/docs/current/queries-with.html).
|
|
353
366
|
# This expression calculates rank by the defined distance function, which measures the distance between the
|
|
354
367
|
# embeddings column and the given embeddings vector. Results are ordered by this rank.
|
|
@@ -409,11 +422,11 @@ class PgVectorHandler(PostgresHandler, VectorStoreHandler):
|
|
|
409
422
|
with self.connection.cursor() as cur:
|
|
410
423
|
# For sparse vectors, use sparsevec type
|
|
411
424
|
vector_column_type = 'sparsevec' if self._is_sparse else 'vector'
|
|
412
|
-
|
|
425
|
+
|
|
413
426
|
# Vector size is required for sparse vectors, optional for dense
|
|
414
427
|
if self._is_sparse and not self._vector_size:
|
|
415
428
|
raise ValueError("vector_size is required for sparse vectors")
|
|
416
|
-
|
|
429
|
+
|
|
417
430
|
# Add vector size specification only if provided
|
|
418
431
|
size_spec = f"({self._vector_size})" if self._vector_size is not None else "()"
|
|
419
432
|
if vector_column_type == 'vector':
|
|
@@ -438,7 +451,7 @@ class PgVectorHandler(PostgresHandler, VectorStoreHandler):
|
|
|
438
451
|
table_name = self._check_table(table_name)
|
|
439
452
|
|
|
440
453
|
if 'metadata' in data.columns:
|
|
441
|
-
|
|
454
|
+
data['metadata'] = data['metadata'].apply(json.dumps)
|
|
442
455
|
|
|
443
456
|
resp = super().insert(table_name, data)
|
|
444
457
|
if resp.resp_type == RESPONSE_TYPE.ERROR:
|
|
@@ -521,3 +534,33 @@ class PgVectorHandler(PostgresHandler, VectorStoreHandler):
|
|
|
521
534
|
"""
|
|
522
535
|
table_name = self._check_table(table_name)
|
|
523
536
|
self.raw_query(f"DROP TABLE IF EXISTS {table_name}")
|
|
537
|
+
|
|
538
|
+
def create_index(self, table_name: str, column_name: str = "embeddings", index_type: Literal['ivfflat', 'hnsw'] = "hnsw", metric_type: str = None):
|
|
539
|
+
"""
|
|
540
|
+
Create an index on the pgvector table.
|
|
541
|
+
Args:
|
|
542
|
+
table_name (str): Name of the table to create the index on.
|
|
543
|
+
column_name (str): Name of the column to create the index on.
|
|
544
|
+
index_type (str): Type of the index to create. Supported types are 'ivfflat' and 'hnsw'.
|
|
545
|
+
metric_type (str): Metric type for the index. Supported types are 'vector_l2_ops', 'vector_ip_ops', and 'vector_cosine_ops'.
|
|
546
|
+
"""
|
|
547
|
+
if metric_type is None:
|
|
548
|
+
metric_type = self.get_metric_type()
|
|
549
|
+
# Check if the index type is supported
|
|
550
|
+
if index_type not in ['ivfflat', 'hnsw']:
|
|
551
|
+
raise ValueError("Invalid index type. Supported types are 'ivfflat' and 'hnsw'.")
|
|
552
|
+
table_name = self._check_table(table_name)
|
|
553
|
+
# first we make sure embedding dimension is set
|
|
554
|
+
embedding_dim_size_df = self.raw_query(f"SELECT vector_dims({column_name}) FROM {table_name} LIMIT 1")
|
|
555
|
+
# check if answer is empty
|
|
556
|
+
if embedding_dim_size_df.empty:
|
|
557
|
+
raise ValueError("Could not determine embedding dimension size. Make sure that knowledge base isn't empty")
|
|
558
|
+
try:
|
|
559
|
+
embedding_dim = int(embedding_dim_size_df.iloc[0, 0])
|
|
560
|
+
# alter table to add dimension
|
|
561
|
+
self.raw_query(f"ALTER TABLE {table_name} ALTER COLUMN {column_name} TYPE vector({embedding_dim})")
|
|
562
|
+
except Exception:
|
|
563
|
+
raise ValueError("Could not determine embedding dimension size. Make sure that knowledge base isn't empty")
|
|
564
|
+
|
|
565
|
+
# Create the index
|
|
566
|
+
self.raw_query(f"CREATE INDEX ON {table_name} USING {index_type} ({column_name} {metric_type})")
|
|
@@ -23,6 +23,7 @@ from mindsdb.integrations.libs.response import (
|
|
|
23
23
|
|
|
24
24
|
logger = log.getLogger(__name__)
|
|
25
25
|
|
|
26
|
+
|
|
26
27
|
class PinotHandler(DatabaseHandler):
|
|
27
28
|
"""
|
|
28
29
|
This handler handles connection and execution of the Apache Pinot statements.
|
|
@@ -182,7 +183,7 @@ class PinotHandler(DatabaseHandler):
|
|
|
182
183
|
api_url = f"{self.connection_data['host']}:{self.connection_data['controller_port']}/tables"
|
|
183
184
|
try:
|
|
184
185
|
result = requests.get(api_url)
|
|
185
|
-
except InvalidSchema
|
|
186
|
+
except InvalidSchema:
|
|
186
187
|
api_url = f"{self.connection_data['scheme']}://{api_url}"
|
|
187
188
|
result = requests.get(api_url)
|
|
188
189
|
|
|
@@ -208,7 +209,7 @@ class PinotHandler(DatabaseHandler):
|
|
|
208
209
|
api_url = f"{self.connection_data['host']}:{self.connection_data['controller_port']}/tables/{table_name}/schema"
|
|
209
210
|
try:
|
|
210
211
|
result = requests.get(api_url)
|
|
211
|
-
except InvalidSchema
|
|
212
|
+
except InvalidSchema:
|
|
212
213
|
api_url = f"{self.connection_data['scheme']}://{api_url}"
|
|
213
214
|
result = requests.get(api_url)
|
|
214
215
|
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import pandas as pd
|
|
2
2
|
from mindsdb.utilities import log
|
|
3
|
-
from mindsdb_sql_parser import parse_sql
|
|
4
3
|
from mindsdb.integrations.libs.api_handler import APIHandler, FuncParser
|
|
5
4
|
from mindsdb.integrations.libs.response import (
|
|
6
5
|
HandlerStatusResponse as StatusResponse,
|
|
@@ -27,12 +26,13 @@ PLAID_ENV = {
|
|
|
27
26
|
|
|
28
27
|
logger = log.getLogger(__name__)
|
|
29
28
|
|
|
29
|
+
|
|
30
30
|
class PlaidHandler(APIHandler):
|
|
31
31
|
'''A class for handling connections and interactions with the Plaid API.
|
|
32
32
|
|
|
33
33
|
Attributes:
|
|
34
34
|
plaid_env (str): Enviroment used by user [ 'sandbox'(default) OR 'development' OR 'production' ].
|
|
35
|
-
client_id (str): Your Plaid API client_id.
|
|
35
|
+
client_id (str): Your Plaid API client_id.
|
|
36
36
|
secret (str): Your Plaid API secret
|
|
37
37
|
access_token (str): The access token for the Plaid account.
|
|
38
38
|
'''
|
|
@@ -119,7 +119,7 @@ class PlaidHandler(APIHandler):
|
|
|
119
119
|
DataFrame
|
|
120
120
|
'''
|
|
121
121
|
|
|
122
|
-
result=pd.DataFrame()
|
|
122
|
+
result = pd.DataFrame()
|
|
123
123
|
if method_name == 'get_balance':
|
|
124
124
|
result = self.get_balance(params=params)
|
|
125
125
|
result = BalanceTable(self).filter_columns(result=result)
|
|
@@ -143,9 +143,9 @@ class PlaidHandler(APIHandler):
|
|
|
143
143
|
self.connect()
|
|
144
144
|
if params.get('last_updated_datetime') is not None:
|
|
145
145
|
options = AccountsBalanceGetRequestOptions(
|
|
146
|
-
min_last_updated_datetime=datetime.strptime(
|
|
146
|
+
min_last_updated_datetime=datetime.strptime(
|
|
147
147
|
params.get('last_updated_datetime')
|
|
148
|
-
|
|
148
|
+
)
|
|
149
149
|
)
|
|
150
150
|
|
|
151
151
|
response = self.api.accounts_balance_get(
|
|
@@ -192,7 +192,7 @@ class PlaidHandler(APIHandler):
|
|
|
192
192
|
end_date = datetime.strptime(params.get('end_date'), '%Y-%m-%d').date()
|
|
193
193
|
else:
|
|
194
194
|
raise Exception('start_date and end_date is required in format YYYY-MM-DD ')
|
|
195
|
-
|
|
195
|
+
|
|
196
196
|
request = TransactionsGetRequest(
|
|
197
197
|
access_token=self.access_token,
|
|
198
198
|
start_date=start_date,
|
|
@@ -207,17 +207,17 @@ class PlaidHandler(APIHandler):
|
|
|
207
207
|
# transactions and retrieve all available data
|
|
208
208
|
while len(transactions) < response['total_transactions']:
|
|
209
209
|
request = TransactionsGetRequest(
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
210
|
+
access_token=self.access_token,
|
|
211
|
+
start_date=start_date,
|
|
212
|
+
end_date=end_date,
|
|
213
|
+
options=TransactionsGetRequestOptions(
|
|
214
|
+
offset=len(transactions)
|
|
215
|
+
)
|
|
216
216
|
)
|
|
217
217
|
response = self.api.transactions_get(request)
|
|
218
218
|
transactions.extend(parse_transaction(response['transactions']))
|
|
219
219
|
|
|
220
|
-
# Converting date column from str
|
|
220
|
+
# Converting date column from str
|
|
221
221
|
df = pd.DataFrame(transactions)
|
|
222
222
|
for i in ['date', 'authorized_date']:
|
|
223
223
|
df[i] = pd.to_datetime(df[i]).dt.date
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import pandas as pd
|
|
2
|
-
from mindsdb.integrations.libs.api_handler import
|
|
2
|
+
from mindsdb.integrations.libs.api_handler import APITable
|
|
3
3
|
from mindsdb.integrations.utilities.sql_utils import extract_comparison_conditions
|
|
4
4
|
from mindsdb_sql_parser import ast
|
|
5
5
|
|
|
@@ -15,8 +15,8 @@ class BalanceTable(APITable):
|
|
|
15
15
|
get_columns(): Get the list of column names for the balance table.
|
|
16
16
|
|
|
17
17
|
'''
|
|
18
|
-
|
|
19
|
-
def select(self, query: ast.Select)
|
|
18
|
+
|
|
19
|
+
def select(self, query: ast.Select):
|
|
20
20
|
'''Select data from the balance table and return it as a pandas DataFrame.
|
|
21
21
|
|
|
22
22
|
Args:
|
|
@@ -34,21 +34,21 @@ class BalanceTable(APITable):
|
|
|
34
34
|
params[i[1]] = i[2]
|
|
35
35
|
else:
|
|
36
36
|
raise Exception("Only equals to '=' is Supported with 'last_updated_datetime'")
|
|
37
|
-
|
|
37
|
+
|
|
38
38
|
result = self.handler.call_plaid_api(method_name='get_balance', params=params)
|
|
39
39
|
|
|
40
40
|
self.filter_columns(query=query, result=result)
|
|
41
41
|
return result
|
|
42
|
-
|
|
42
|
+
|
|
43
43
|
def get_columns(self):
|
|
44
44
|
'''Get the list of column names for the balance table.
|
|
45
|
-
|
|
45
|
+
|
|
46
46
|
Returns:
|
|
47
47
|
list: A list of column names for the balance table.
|
|
48
48
|
|
|
49
49
|
'''
|
|
50
50
|
return [
|
|
51
|
-
'account_id',
|
|
51
|
+
'account_id',
|
|
52
52
|
'account_name',
|
|
53
53
|
'account_mask',
|
|
54
54
|
'account_type',
|
|
@@ -58,11 +58,11 @@ class BalanceTable(APITable):
|
|
|
58
58
|
'balance_unofficial_currency_code',
|
|
59
59
|
'balance_available',
|
|
60
60
|
'balance_current',
|
|
61
|
-
'balance_limit'
|
|
61
|
+
'balance_limit'
|
|
62
62
|
]
|
|
63
63
|
|
|
64
64
|
def filter_columns(self, result: pd.DataFrame, query: ast.Select = None):
|
|
65
|
-
|
|
65
|
+
|
|
66
66
|
columns = []
|
|
67
67
|
if query is not None:
|
|
68
68
|
for target in query.targets:
|
|
@@ -103,7 +103,7 @@ class TransactionTable(BalanceTable):
|
|
|
103
103
|
|
|
104
104
|
'''
|
|
105
105
|
|
|
106
|
-
def select(self, query: ast.Select)
|
|
106
|
+
def select(self, query: ast.Select):
|
|
107
107
|
'''Select data from the transaction table and return it as a pandas DataFrame.
|
|
108
108
|
|
|
109
109
|
Args:
|
|
@@ -155,5 +155,3 @@ class TransactionTable(BalanceTable):
|
|
|
155
155
|
'payment_channel',
|
|
156
156
|
'pending',
|
|
157
157
|
]
|
|
158
|
-
|
|
159
|
-
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
from collections import OrderedDict
|
|
2
|
-
|
|
3
|
-
from mindsdb.integrations.libs.const import HANDLER_CONNECTION_ARG_TYPE as ARG_TYPE
|
|
4
1
|
from mindsdb.integrations.handlers.mysql_handler import Handler as MySQLHandler
|
|
5
2
|
|
|
6
3
|
|
|
@@ -9,6 +6,6 @@ class PlanetScaleHandler(MySQLHandler):
|
|
|
9
6
|
This handler handles the connection and execution of queries against PlanetScale.
|
|
10
7
|
"""
|
|
11
8
|
name = 'planet_scale'
|
|
12
|
-
|
|
9
|
+
|
|
13
10
|
def __init__(self, name, **kwargs):
|
|
14
11
|
super().__init__(name, **kwargs)
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
from .__about__ import __version__ as version
|
|
2
|
+
from .__about__ import __description__ as description
|
|
1
3
|
from mindsdb.integrations.libs.const import HANDLER_TYPE
|
|
2
4
|
from mindsdb.utilities import log
|
|
3
5
|
|
|
4
6
|
logger = log.getLogger(__name__)
|
|
5
7
|
|
|
6
|
-
from .__about__ import __description__ as description
|
|
7
|
-
from .__about__ import __version__ as version
|
|
8
8
|
|
|
9
9
|
try:
|
|
10
10
|
from .portkey_handler import PortkeyHandler as Handler
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import time
|
|
2
2
|
import json
|
|
3
|
-
from typing import Optional
|
|
3
|
+
from typing import Optional, Any
|
|
4
4
|
|
|
5
5
|
import pandas as pd
|
|
6
|
+
from pandas import DataFrame
|
|
6
7
|
import psycopg
|
|
7
|
-
from psycopg
|
|
8
|
+
from psycopg import Column as PGColumn, Cursor
|
|
9
|
+
from psycopg.postgres import TypeInfo, types as pg_types
|
|
8
10
|
from psycopg.pq import ExecStatus
|
|
9
|
-
from pandas import DataFrame
|
|
10
11
|
|
|
11
12
|
from mindsdb_sql_parser import parse_sql
|
|
12
13
|
from mindsdb.utilities.render.sqlalchemy_render import SqlalchemyRender
|
|
@@ -27,7 +28,7 @@ logger = log.getLogger(__name__)
|
|
|
27
28
|
SUBSCRIBE_SLEEP_INTERVAL = 1
|
|
28
29
|
|
|
29
30
|
|
|
30
|
-
def _map_type(internal_type_name: str) -> MYSQL_DATA_TYPE:
|
|
31
|
+
def _map_type(internal_type_name: str | None) -> MYSQL_DATA_TYPE:
|
|
31
32
|
"""Map Postgres types to MySQL types.
|
|
32
33
|
|
|
33
34
|
Args:
|
|
@@ -36,14 +37,22 @@ def _map_type(internal_type_name: str) -> MYSQL_DATA_TYPE:
|
|
|
36
37
|
Returns:
|
|
37
38
|
MYSQL_DATA_TYPE: The MySQL type that corresponds to the Postgres type.
|
|
38
39
|
"""
|
|
40
|
+
fallback_type = MYSQL_DATA_TYPE.VARCHAR
|
|
41
|
+
|
|
42
|
+
if internal_type_name is None:
|
|
43
|
+
return fallback_type
|
|
44
|
+
|
|
39
45
|
internal_type_name = internal_type_name.lower()
|
|
40
46
|
types_map = {
|
|
41
|
-
('smallint', '
|
|
42
|
-
('
|
|
47
|
+
('smallint', 'smallserial'): MYSQL_DATA_TYPE.SMALLINT,
|
|
48
|
+
('integer', 'int', 'serial'): MYSQL_DATA_TYPE.INT,
|
|
49
|
+
('bigint', 'bigserial'): MYSQL_DATA_TYPE.BIGINT,
|
|
50
|
+
('real', 'float'): MYSQL_DATA_TYPE.FLOAT,
|
|
43
51
|
('numeric', 'decimal'): MYSQL_DATA_TYPE.DECIMAL,
|
|
44
52
|
('double precision',): MYSQL_DATA_TYPE.DOUBLE,
|
|
45
53
|
('character varying', 'varchar'): MYSQL_DATA_TYPE.VARCHAR,
|
|
46
|
-
|
|
54
|
+
# NOTE: if return chars-types as mysql's CHAR, then response will be padded with spaces, so return as TEXT
|
|
55
|
+
('money', 'character', 'char', 'bpchar', 'bpchar', 'text'): MYSQL_DATA_TYPE.TEXT,
|
|
47
56
|
('timestamp', 'timestamp without time zone', 'timestamp with time zone'): MYSQL_DATA_TYPE.DATETIME,
|
|
48
57
|
('date', ): MYSQL_DATA_TYPE.DATE,
|
|
49
58
|
('time', 'time without time zone', 'time with time zone'): MYSQL_DATA_TYPE.TIME,
|
|
@@ -55,8 +64,51 @@ def _map_type(internal_type_name: str) -> MYSQL_DATA_TYPE:
|
|
|
55
64
|
if internal_type_name in db_types_list:
|
|
56
65
|
return mysql_data_type
|
|
57
66
|
|
|
58
|
-
logger.
|
|
59
|
-
return
|
|
67
|
+
logger.debug(f"Postgres handler type mapping: unknown type: {internal_type_name}, use VARCHAR as fallback.")
|
|
68
|
+
return fallback_type
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def _make_table_response(result: list[tuple[Any]], cursor: Cursor) -> Response:
|
|
72
|
+
"""Build response from result and cursor.
|
|
73
|
+
|
|
74
|
+
Args:
|
|
75
|
+
result (list[tuple[Any]]): result of the query.
|
|
76
|
+
cursor (psycopg.Cursor): cursor object.
|
|
77
|
+
|
|
78
|
+
Returns:
|
|
79
|
+
Response: response object.
|
|
80
|
+
"""
|
|
81
|
+
description: list[PGColumn] = cursor.description
|
|
82
|
+
mysql_types: list[MYSQL_DATA_TYPE] = []
|
|
83
|
+
for column in description:
|
|
84
|
+
pg_type_info: TypeInfo = pg_types.get(column.type_code)
|
|
85
|
+
if pg_type_info is None:
|
|
86
|
+
logger.warning(f'Postgres handler: unknown type: {column.type_code}')
|
|
87
|
+
regtype: str = pg_type_info.regtype if pg_type_info is not None else None
|
|
88
|
+
mysql_type = _map_type(regtype)
|
|
89
|
+
mysql_types.append(mysql_type)
|
|
90
|
+
|
|
91
|
+
# region cast int and bool to nullable types
|
|
92
|
+
serieses = []
|
|
93
|
+
for i, mysql_type in enumerate(mysql_types):
|
|
94
|
+
expected_dtype = None
|
|
95
|
+
if mysql_type in (
|
|
96
|
+
MYSQL_DATA_TYPE.SMALLINT, MYSQL_DATA_TYPE.INT, MYSQL_DATA_TYPE.MEDIUMINT,
|
|
97
|
+
MYSQL_DATA_TYPE.BIGINT, MYSQL_DATA_TYPE.TINYINT
|
|
98
|
+
):
|
|
99
|
+
expected_dtype = 'Int64'
|
|
100
|
+
elif mysql_type in (MYSQL_DATA_TYPE.BOOL, MYSQL_DATA_TYPE.BOOLEAN):
|
|
101
|
+
expected_dtype = 'boolean'
|
|
102
|
+
serieses.append(pd.Series([row[i] for row in result], dtype=expected_dtype, name=description[i].name))
|
|
103
|
+
df = pd.concat(serieses, axis=1, copy=False)
|
|
104
|
+
# endregion
|
|
105
|
+
|
|
106
|
+
return Response(
|
|
107
|
+
RESPONSE_TYPE.TABLE,
|
|
108
|
+
data_frame=df,
|
|
109
|
+
affected_rows=cursor.rowcount,
|
|
110
|
+
mysql_types=mysql_types
|
|
111
|
+
)
|
|
60
112
|
|
|
61
113
|
|
|
62
114
|
class PostgresHandler(DatabaseHandler):
|
|
@@ -199,13 +251,13 @@ class PostgresHandler(DatabaseHandler):
|
|
|
199
251
|
for column_index, column_name in enumerate(df.columns):
|
|
200
252
|
col = df[column_name]
|
|
201
253
|
if str(col.dtype) == 'object':
|
|
202
|
-
|
|
203
|
-
if
|
|
204
|
-
col = col.fillna(0)
|
|
254
|
+
pg_type_info: TypeInfo = pg_types.get(description[column_index].type_code) # type_code is int!?
|
|
255
|
+
if pg_type_info is not None and pg_type_info.name in types_map:
|
|
256
|
+
col = col.fillna(0) # TODO rework
|
|
205
257
|
try:
|
|
206
|
-
df[column_name] = col.astype(types_map[
|
|
258
|
+
df[column_name] = col.astype(types_map[pg_type_info.name])
|
|
207
259
|
except ValueError as e:
|
|
208
|
-
logger.error(f'Error casting column {col.name} to {types_map[
|
|
260
|
+
logger.error(f'Error casting column {col.name} to {types_map[pg_type_info.name]}: {e}')
|
|
209
261
|
df.columns = columns
|
|
210
262
|
|
|
211
263
|
@profiler.profile()
|
|
@@ -232,16 +284,7 @@ class PostgresHandler(DatabaseHandler):
|
|
|
232
284
|
response = Response(RESPONSE_TYPE.OK, affected_rows=cur.rowcount)
|
|
233
285
|
else:
|
|
234
286
|
result = cur.fetchall()
|
|
235
|
-
|
|
236
|
-
result,
|
|
237
|
-
columns=[x.name for x in cur.description]
|
|
238
|
-
)
|
|
239
|
-
self._cast_dtypes(df, cur.description)
|
|
240
|
-
response = Response(
|
|
241
|
-
RESPONSE_TYPE.TABLE,
|
|
242
|
-
data_frame=df,
|
|
243
|
-
affected_rows=cur.rowcount
|
|
244
|
-
)
|
|
287
|
+
response = _make_table_response(result, cur)
|
|
245
288
|
connection.commit()
|
|
246
289
|
except Exception as e:
|
|
247
290
|
logger.error(f'Error running query: {query} on {self.database}, {e}!')
|
|
@@ -257,6 +300,44 @@ class PostgresHandler(DatabaseHandler):
|
|
|
257
300
|
|
|
258
301
|
return response
|
|
259
302
|
|
|
303
|
+
def query_stream(self, query: ASTNode, fetch_size: int = 1000):
|
|
304
|
+
"""
|
|
305
|
+
Executes a SQL query and stream results outside by batches
|
|
306
|
+
|
|
307
|
+
:param query: An ASTNode representing the SQL query to be executed.
|
|
308
|
+
:param fetch_size: size of the batch
|
|
309
|
+
:return: generator with query results
|
|
310
|
+
"""
|
|
311
|
+
query_str, params = self.renderer.get_exec_params(query, with_failback=True)
|
|
312
|
+
|
|
313
|
+
need_to_close = not self.is_connected
|
|
314
|
+
|
|
315
|
+
connection = self.connect()
|
|
316
|
+
with connection.cursor() as cur:
|
|
317
|
+
try:
|
|
318
|
+
if params is not None:
|
|
319
|
+
cur.executemany(query_str, params)
|
|
320
|
+
else:
|
|
321
|
+
cur.execute(query_str)
|
|
322
|
+
|
|
323
|
+
if cur.pgresult is not None and ExecStatus(cur.pgresult.status) != ExecStatus.COMMAND_OK:
|
|
324
|
+
while True:
|
|
325
|
+
result = cur.fetchmany(fetch_size)
|
|
326
|
+
if not result:
|
|
327
|
+
break
|
|
328
|
+
df = DataFrame(
|
|
329
|
+
result,
|
|
330
|
+
columns=[x.name for x in cur.description]
|
|
331
|
+
)
|
|
332
|
+
self._cast_dtypes(df, cur.description)
|
|
333
|
+
yield df
|
|
334
|
+
connection.commit()
|
|
335
|
+
finally:
|
|
336
|
+
connection.rollback()
|
|
337
|
+
|
|
338
|
+
if need_to_close:
|
|
339
|
+
self.disconnect()
|
|
340
|
+
|
|
260
341
|
def insert(self, table_name: str, df: pd.DataFrame) -> Response:
|
|
261
342
|
need_to_close = not self.is_connected
|
|
262
343
|
|