Trabajando con bases de datos a través de TableStudio
TableStudio es la aplicación de base de datos del usuario en su Mac. Sus herramientas MCP acceden a las conexiones guardadas sin necesidad de credenciales, y vienen con redes de seguridad que una sesión psql en crudo no tiene: una ejecución simulada exacta de una escritura contra las filas reales, copias desechables tipo sandbox y una bandeja de revisión donde el usuario aprueba los cambios. Úsalas para el trabajo con bases de datos en lugar de psql, mysql, sqlite3 o un script que abra su propia conexión.
Los nombres de las herramientas a continuación son los de TableStudio. Tu cliente puede mostrarlos con un prefijo (en Claude Code: mcp__plugin_tablestudio_tablestudio__list_connections). Si están diferidos, cárgalos con ese nombre antes de la primera llamada.
1. Encuentra la base de datos correcta antes de hacer nada
La nota de Contexto de base de datos de la sesión, proveniente del plugin de TableStudio, suele nombrar la conexión de TableStudio detrás de cada configuración de base de datos del repositorio, con su id y entorno. Usa ese id como connection_id. La nota también indica cuándo las herramientas de TableStudio no están disponibles y qué debe hacer el usuario al respecto.
Sin la nota, o para una base de datos que no nombra:
- Llama a
list_connections. Cada conexión puede incluir lo que el usuario le dijo a TableStudio sobre ella:project: el proyecto al que pertenece. Prefiere conexiones cuyo proyecto coincida con el repo en el que estás trabajando.environment:development,stagingoproduction. Ausente significa sin etiqueta, no development.read_only: TableStudio rechaza escrituras en ella. Staging sigue funcionando.location:local(este Mac),remoteosandbox(una copia desechable, segura para experimentar).agent_writes:directsignifica que execute_query puede escribir allí (cuando las escrituras están activadas);reviewsignifica que cada cambio pasa porstage_migrationpara que el usuario lo aplique. TableStudio decide esto, no tú: producción, y cualquier base de datos remota que el usuario no haya etiquetado como development o staging, sonreview.notes: las notas del usuario sobre las convenciones de la base de datos (borrados suaves, dinero en céntimos, nombres). Síguelas.
- Empareja primero por proyecto, luego confirma con
host,portydatabasecontra la configuración del propio proyecto (.env, config). - Si dos conexiones podrían ser la que el usuario quiere, o no puedes saber si una es producción, pregunta. No adivines.
Luego:
- Llama a
describe_capabilitiesuna vez antes de planificar cualquier cosa más allá de una lectura. Indica si las escrituras directas, el staging y los sandboxes están permitidos en este momento, y nombra la configuración detrás de cada uno. Planifica en torno a ello en lugar de encontrar un límite al ser rechazado. agent_writes: review(producción, o remota y sin etiqueta) significa que nunca escribas directamente en ella: prepara los cambios para revisión. TableStudio rechaza una escritura directa de todos modos, así que planifica el staging desde el principio.- Verifica
engine(postgres, mysql, sqlite, d1, clickhouse) antes de escribir SQL, y escribe en ese dialecto. - Una base de datos que no está guardada en TableStudio no se puede alcanzar a través de sus herramientas. Pide al usuario que la agregue en TableStudio. Nunca pidas una contraseña en el chat.
- Si una llamada falla porque la base de datos es inalcanzable, llama a
connection_status. Cuando dice que un servidor local está detenido, llama astart_local_databasecon elinstance_idque te proporcione.
2. Lectura e investigación
- Busca en lugar de adivinar nombres:
search_schemaencuentra tablas y columnas por fragmento de nombre, yget_table_ddlda la estructura completa, índices, claves foráneas yreferenced_by. - Ejecuta lecturas con
execute_query. Selecciona las columnas que necesitas, filtra, agrega y usaLIMIT. Los resultados están limitados (max_rows, por defecto 200), así que un resultadotruncatedno es la respuesta completa. - Las lecturas se ejecutan en una transacción de solo lectura con un límite de 30 segundos, incluso en producción, por lo que una lectura no puede cambiar datos ni siquiera a través de una función. Mantenlas económicas de todos modos: en una tabla grande de producción, filtra por una columna indexada o usa las estimaciones de filas de
database_overviewen lugar decount(*). - Un bug de datos: reprodúcelo primero en los datos. Encuentra las filas incorrectas, cuéntalas y encuentra cuándo comenzaron (
min(created_at)). Luego lee el código que las escribe. Muestra al usuario la consulta que lo prueba. Corrige el código, y si las filas necesitan reparación, eso es un cambio de datos (sección 3). - Nunca pegues secretos, contraseñas o cadenas de conexión en SQL, código, documentos o chat. El único lugar donde pertenece una cadena de conexión es el archivo de entorno gitignored del proyecto, para una base de datos local (el skill de bases de datos locales cubre
get_connection_url).
3. Cambiar datos (INSERT, UPDATE, DELETE)
En PostgreSQL:
- Escribe la sentencia, luego llama a
preflight_statementcon ella. Obtienes unverdict(looks_fine,reviewowould_fail),dry_run.rows(exactamente cuántas filas cambiaría, solo lectura), cascadas a otras tablas y qué haría que fallara. - Dile al usuario lo que hará en palabras simples: "Esto actualiza 142 filas en
invoices; no hay cascadas." Si el veredicto eswould_fail, corrige la sentencia primero. Si esreview, explica por qué. - Luego, ya sea:
agent_writes: direct, y las escrituras directas están permitidas:execute_queryconexpected_rowsestablecido endry_run.rows. Solo confirma si exactamente esa cantidad de filas cambian, y revierte en caso contrario. En una base de datos PostgreSQL remota, TableStudio rechaza un cambio de datos sinexpected_rows.agent_writes: review, escrituras no permitidas, o cualquier cosa que el usuario debería ver primero:stage_migrationcon untitleclaro, el SQL, y unarationaleque incluya el conteo de la ejecución simulada ("Anula las 142 facturas duplicadas encontradas por …"). Va a la cola de revisión del usuario en el Centro de Agentes de TableStudio y no se ejecuta.
En otros motores no hay ejecución simulada: primero ejecuta un SELECT count(*) con el mismo WHERE, reporta el conteo, luego sigue la misma regla de ejecutar o preparar.
Antes de cualquier cosa destructiva en una base de datos que importa (un DELETE grande, un DROP, un TRUNCATE), llama a create_restore_point cuando los sandboxes estén habilitados, y dile al usuario que lo hiciste.
4. Cambiar el esquema
Si el repositorio usa una herramienta de migración (Prisma, Drizzle, Rails, Django, Alembic, Laravel, Supabase, Knex, Ecto, TypeORM, Wrangler D1, o archivos SQL numerados simples; el contexto de la sesión lo nombra cuando el plugin lo detectó), el cambio pertenece a esa herramienta:
- Haz el cambio a la manera de la herramienta: edita el esquema y genera una migración, o escribe el archivo de migración.
- Aplícalo a la base de datos de desarrollo local con el comando de desarrollo de la herramienta.
- Verifícalo contra datos reales (abajo).
- Deja la aplicación en cualquier otro lugar al proceso de despliegue normal del usuario. Nunca ejecutes el comando de despliegue de la herramienta contra producción tú mismo.
Ejecutar ALTER TABLE directamente cuando una herramienta de migración posee el esquema deja el historial de la herramienta desincronizado con la base de datos, lo que rompe el siguiente despliegue.
Si no hay una herramienta de migración, o el usuario pide un cambio único a una base de datos existente:
- Lee primero la tabla con
get_table_ddl. Verificareferenced_byantes de eliminar o renombrar algo. - Pruébalo en una copia:
create_sandbox(data:nonesolo para esquema,samplepara una porción de filas reales), ejecuta el DDL en la conexión del sandbox conexecute_query, y verifica que hace lo que pretendías. - Muestra la diferencia con
compare_schemas(sandbox comosource_connection_id, la base de datos real comotarget_connection_id). - Propónlo con
stage_migrationen la conexión real. El usuario lo aplica desde TableStudio.
Verificar una migración contra datos reales
Una migración que funciona en la base de datos local aún puede fallar, o bloquear la aplicación, donde están las filas reales. Antes de dar una migración por terminada, verifícala en modo solo lectura contra la base de datos a la que se desplegará (generalmente staging o producción, desde la nota de sesión o list_connections):
-
get_table_ddlpara cada tabla que altera: cuántas filas, sus índices y qué la referencia. -
Para cada restricción que agrega,
execute_queryel SELECT que encuentra filas que la romperían:NOT NULL:SELECT count(*) FROM t WHERE col IS NULLUNIQUE:SELECT col, count(*) FROM t GROUP BY col HAVING count(*) > 1 LIMIT 20- una clave foránea: filas hijas cuyo padre no existe (
LEFT JOIN … WHERE parent.id IS NULL) - un
CHECK, o un tipo o longitud más restrictivos: filas fuera del nuevo rango
Cualquier fila significa que el despliegue fallaría. Agrega un paso de relleno o limpieza a la migración, y dilo.
-
En PostgreSQL, marca los pasos que bloquean o reescriben una tabla grande (ver abajo) y cambia al patrón seguro.
-
Cuando el cambio es complicado, ejecútalo realmente en una copia:
create_sandboxdesde esa conexión condata: "sample",execute_queryel SQL de la migración en el sandbox, luegocompare_schemas.
Dile al usuario lo que verificaste y lo que encontraste ("orders.status tiene 0 NULLs en 1.2M filas, así que SET NOT NULL es seguro"). Todo esto es solo lectura: nunca apliques la migración en ningún lugar que no sea la base de datos de desarrollo local.
Bloqueos en PostgreSQL
- Construir un índice en una tabla grande y ocupada: usa
CREATE INDEX CONCURRENTLY. No puede ejecutarse dentro de una transacción, así que no envuelvas esa sentencia enBEGIN … COMMIT. - Agregar una columna
NOT NULLcon un valor predeterminado volátil, cambiar un tipo de columna o agregar una clave foránea puede reescribir o bloquear la tabla. Dilo en la justificación y considera dividirlo en pasos seguros (agrega la columna nullable, rellena en lotes, luegoSET NOT NULL; agrega una clave foráneaNOT VALID, luegoVALIDATE CONSTRAINT). schema_issuesdevuelve SQL correctivo con unlock_impactpara cada problema. Léelo antes de proponer una corrección.
5. Después de que preparas algo
- Dile al usuario que está esperando su revisión en TableStudio y no se ha ejecutado, y dale el
review_urldel resultado como enlace. Se abre la revisión con el impacto del cambio (filas que toca, bloqueos, qué fallaría), un diagrama del esquema después del cambio y un plan de deshacer. Nunca digas que un cambio preparado fue aplicado. - Si el usuario pide cambios,
list_staged_migrationsmuestrastatus: changes_requestedcon su nota enreview_feedback. Revísalo conupdate_staged_migration(mismomigration_id) en lugar de preparar una segunda copia, luego diles que está listo para que lo vean de nuevo. Para retirarlo, usaremove_staged_migration. list_staged_migrationstambién muestra si el usuario lo aplicó, lo ignoró o falló.
Cuando el usuario pregunta qué está esperándolos ("¿qué preparaste?", "¿se ejecutó mi migración?"), llama a list_staged_migrations para las conexiones de este repositorio. Reporta primero las pendientes, de la más reciente a la más antigua: el título, la conexión, cuándo fue preparada, su review_url, y una línea sobre qué hace y qué tan riesgosa es (¿bloquea o reescribe una tabla grande, elimina datos, o carece de un WHERE?). Luego las que tienen cambios solicitados, con la nota del usuario, y las que fallaron, con el error. Di claramente que el usuario aplica, devuelve o ignora en el Centro de Agentes de TableStudio; tú no puedes aplicarlas tú mismo.
6. Cuando TableStudio dice que no
- Un rechazo que nombra una configuración (por ejemplo, las escrituras están desactivadas) es una elección del usuario. Diles qué configuración lo permitiría, ofrece preparar el cambio en su lugar y detente. No busques una ruta alternativa.
- Si las herramientas de TableStudio no están disponibles en absoluto, la nota de sesión dice por qué: la aplicación está cerrada, su servidor MCP está apagado (Configuración → MCP), o el cliente aún no está conectado a él. Transmite la solución que da. En Claude Code, el usuario puede reconectarse con
/mcpuna vez que TableStudio esté abierto. - Un rechazo con
blocked: production_review_requiredoreview_requiredsignifica que esa conexión solo acepta cambios a través de revisión: prepáralo.dry_run_requiredsignifica ejecutapreflight_statementprimero y pasaexpected_rows.side_effect_functionsignifica que la sentencia llama a algo que actúa fuera de una transacción; muestra al usuario el SQL en su lugar. - El guardia de shell del plugin bloquea los comandos de shell que escriben en producción. Trata un bloqueo como una señal para usar los pasos anteriores, no como algo que sortear.
- Todo lo que haces a través de TableStudio se muestra al usuario en su Centro de Agentes, agrupado por esta conversación.