---
name: metabase_execute_query
kind: function
lang: py
domain: infra
version: "1.0.0"
purity: impure
signature: "def metabase_execute_query(client: MetabaseClient, database_id: int, sql: str, max_results: int = 0) -> dict"
description: "Ejecuta query SQL ad-hoc contra Metabase sin guardarla como card. Util para exploracion rapida. Endpoint: POST /api/dataset."
tags: [metabase, query, execute, sql, dataset, api, python, extractor]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: "error_go_core"
imports: [httpx]
params:
  - name: client
    desc: "instancia autenticada de MetabaseClient"
  - name: database_id
    desc: "ID de la base de datos contra la que ejecutar la query"
  - name: sql
    desc: "sentencia SQL a ejecutar (sin guardar como card)"
  - name: max_results
    desc: "límite de filas a retornar (0=default 2000)"
output: "dict: resultados con status, row_count, running_time, data.columns, data.rows"
tested: false
tests: []
test_file_path: ""
file_path: "python/functions/metabase/cards.py"
---

## Ejemplo

```python
result = metabase_execute_query(client, 1, "SELECT * FROM users LIMIT 10")
print(f"{result['row_count']} filas en {result['running_time']}ms")
```

## Notas

Misma respuesta que metabase_execute_card. Default 2000 filas, override con max_results.
