Files
fn_registry/apps/auto_metabase/scripts/seed_test_data.py
T
egutierrez 310b409ae0 feat(auto_metabase): push-all + describe/sql + auto-inject de dashcards
- push_all(): pushea todos los YAMLs de un proyecto (cards primero,
  dashboards despues), solo CREATE/UPDATE, resiliente a fallos por item
- explore.py: comandos describe (schema de DB) y sql (query ad-hoc con
  limite, cap 5MB, bloqueo de escrituras destructivas)
- payload.py: auto-inyecta id:-N, visualization_settings:{} y
  parameter_mappings:[] en dashcards nuevas para evitar 500 en push
- test_local: 11 cards + 3 dashboards sobre Sample Database de Metabase
- registry.db regenerado con auto_metabase_py_analytics indexada

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 13:14:05 +02:00

123 lines
4.1 KiB
Python

"""Crea database + cards + dashboard de prueba en Metabase para validar pull/push.
Usa la propia Postgres interna de Metabase (auto_metabase_test-postgres) como
database de prueba, ya que es accesible desde el container metabase via la
red docker compartida.
"""
import sys
from pathlib import Path
APP_DIR = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(APP_DIR.parent.parent / "python" / "functions"))
sys.path.insert(0, str(APP_DIR))
from main import get_client # noqa: E402
from metabase.databases import metabase_add_database, metabase_list_databases # noqa: E402
from metabase.cards import metabase_create_card, metabase_list_cards # noqa: E402
from metabase.dashboards import ( # noqa: E402
metabase_create_dashboard,
metabase_list_dashboards,
metabase_update_dashboard,
)
def find_or_create_database(client) -> int:
dbs = metabase_list_databases(client)
# list_databases puede retornar un dict con 'data' o una lista directa
items = dbs["data"] if isinstance(dbs, dict) and "data" in dbs else dbs
for db in items:
if db.get("name") == "metabase_internal_pg":
print(f" database existente id={db['id']}")
return db["id"]
db = metabase_add_database(
client,
name="metabase_internal_pg",
engine="postgres",
details={
"host": "auto_metabase_test-postgres",
"port": 5432,
"dbname": "metabase",
"user": "metabase",
"password": "metabase",
"ssl": False,
},
)
print(f" database creada id={db['id']}")
return db["id"]
def find_or_create_card(client, name: str, db_id: int, sql: str, display: str = "table") -> int:
cards = metabase_list_cards(client)
for c in cards:
if c.get("name") == name:
print(f" card '{name}' existente id={c['id']}")
return c["id"]
card = metabase_create_card(
client,
name=name,
dataset_query={
"type": "native",
"native": {"query": sql},
"database": db_id,
},
display=display,
)
print(f" card '{name}' creada id={card['id']}")
return card["id"]
def find_or_create_dashboard(client, name: str) -> int:
dashes = metabase_list_dashboards(client)
for d in dashes:
if d.get("name") == name:
print(f" dashboard '{name}' existente id={d['id']}")
return d["id"]
d = metabase_create_dashboard(client, name=name, description="Dashboard de prueba para auto_metabase")
print(f" dashboard '{name}' creado id={d['id']}")
return d["id"]
def main():
client = get_client()
print("Seeding test data en Metabase...")
print("\n[1] Database")
db_id = find_or_create_database(client)
print("\n[2] Cards")
c1 = find_or_create_card(
client, "test_count_users", db_id,
"SELECT COUNT(*) AS users FROM core_user", "scalar",
)
c2 = find_or_create_card(
client, "test_users_by_locale", db_id,
"SELECT COALESCE(locale, 'unknown') AS locale, COUNT(*) AS n FROM core_user GROUP BY locale ORDER BY n DESC",
"bar",
)
print("\n[3] Dashboard con cards")
dash_id = find_or_create_dashboard(client, "auto_metabase test dashboard")
# Re-fetch dashboard para ver estado actual
from metabase.dashboards import metabase_get_dashboard
dash = metabase_get_dashboard(client, dash_id)
existing_card_ids = {dc.get("card_id") for dc in dash.get("dashcards", [])}
if c1 in existing_card_ids and c2 in existing_card_ids:
print(f" dashboard ya tiene las {len(dash.get('dashcards', []))} dashcards esperadas")
else:
# Construir dashcards: id negativo => nueva
new_dashcards = [
{"id": -1, "card_id": c1, "row": 0, "col": 0, "size_x": 6, "size_y": 4},
{"id": -2, "card_id": c2, "row": 0, "col": 6, "size_x": 6, "size_y": 4},
]
metabase_update_dashboard(client, dash_id, dashcards=new_dashcards)
print(f" dashcards añadidas: {len(new_dashcards)}")
print(f"\nListo. Abre http://localhost:3000/dashboard/{dash_id}")
if __name__ == "__main__":
main()