Listado y Cambio de Bases de Datos en PostgreSQL: La Guía Técnica Completa
PostgreSQL gestiona múltiples bases de datos aisladas dentro de una única instancia de servidor, cada una con su propio esquema, roles y privilegios. Para listar todas las bases de datos, ejecute l dentro de psql o consulte SELECT datname FROM pg_catalog.pg_database; desde cualquier sesión. Para cambiar de base de datos, debe abrir una nueva conexión — PostgreSQL impone una vinculación estricta de sesión a base de datos sin un equivalente al comando USE dentro de la sesión.
Esta guía cubre todos los métodos disponibles para enumerar y conectarse a bases de datos PostgreSQL, desde comandos psql sin procesar y consultas al catálogo del sistema hasta cadenas de conexión, consideraciones de pg_hba.conf y patrones de flujo de trabajo con múltiples bases de datos utilizados en entornos de producción.
Por qué el cambio de base de datos en PostgreSQL funciona de manera diferente
La mayoría de los desarrolladores que vienen de MySQL esperan un comando USE database_name;. PostgreSQL omite esto deliberadamente. Cada sesión de PostgreSQL está vinculada exactamente a una base de datos en el momento de la conexión, y esa vinculación es inmutable durante toda la vida de la sesión. Esta es una decisión arquitectónica enraizada en el modelo de procesos de PostgreSQL: el proceso backend (postgres) carga el catálogo del sistema de la base de datos en la memoria compartida al inicio, y cambiar de catálogo a mitad de sesión requeriría de todos modos un reinicio completo del proceso.
Comprender esta restricción de antemano evita horas de depuración y determina cómo se diseñan las herramientas de múltiples bases de datos, los grupos de conexiones y las configuraciones de aplicaciones.
Listar todas las bases de datos en PostgreSQL
Método 1: El metacomando l en psql
La forma más rápida de enumerar bases de datos es el metacomando l (alias: list) dentro de una sesión interactiva de psql.
psql -U postgresUna vez conectado:
lEsto produce una tabla formateada similar a:
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+----------+----------+-------------+-------------+-----------------------
myapp_db | appuser | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
analytics | analyst | UTF8 | en_US.UTF-8 | en_US.UTF-8 | analyst=CTc/analyst
postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |Las columnas revelan más que solo nombres: Encoding importa al migrar datos entre servidores, Collate afecta el orden de clasificación y el comportamiento de los índices, y Access privileges utiliza la notación ACL de PostgreSQL (C = CONNECT, T = TEMPORARY, c = CREATE).
Para obtener detalles extendidos que incluyan el tablespace y los límites de conexión, use:
l+Método 2: Consultar el catálogo del sistema pg_database
Para scripting, monitoreo o introspección a nivel de aplicación, consulte la vista pg_catalog.pg_database directamente. Esto funciona desde cualquier base de datos del clúster porque los catálogos del sistema son visibles globalmente.
SELECT
datname AS database_name,
pg_catalog.pg_get_userbyid(datdba) AS owner,
pg_encoding_to_char(encoding) AS encoding,
datcollate AS collation,
datctype AS ctype,
datconnlimit AS connection_limit,
pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(datname)) AS size
FROM pg_catalog.pg_database
WHERE datistemplate = false
ORDER BY datname;Filtrar datistemplate = false excluye template0 y template1 de los resultados — esas son plantillas del sistema, no bases de datos operativas. La columna datconnlimit es crítica en entornos compartidos: un valor de -1 significa ilimitado, mientras que cualquier entero positivo limita las conexiones concurrentes a esa base de datos.
Consejo de producción: Agregue pg_database_size() a sus consultas de monitoreo. Una base de datos que crece silenciosamente más allá de la capacidad del tablespace es una causa común de fallos de escritura que son difíciles de diagnosticar después del hecho.
Método 3: Listar bases de datos sin entrar a psql
Para scripts de shell y canalizaciones de automatización, puede recuperar la lista de bases de datos sin entrar en una sesión interactiva:
psql -U postgres -c "l"O para una salida limpia y analizable por scripts:
psql -U postgres -t -c "SELECT datname FROM pg_database WHERE datistemplate = false;"El indicador -t suprime los encabezados de columna y los recuentos de filas, devolviendo solo valores sin procesar — ideal para canalizar hacia grep, awk o arrays de Bash.
Para exportar la lista a un archivo:
psql -U postgres -t -A -c "SELECT datname FROM pg_database WHERE datistemplate = false;" > db_list.txt-A deshabilita la alineación de columnas, produciendo un nombre de base de datos por línea.
Cambiar entre bases de datos en PostgreSQL
Dado que no puede cambiar de base de datos dentro de una sesión activa, el enfoque correcto es terminar la conexión actual y establecer una nueva apuntando a la base de datos deseada. Hay varias formas de hacer esto de manera eficiente.
Método 1: Salir y reconectarse desde el shell
Dentro de psql, salga de la sesión actual:
q
Luego conéctese a la base de datos de destino:
psql -U postgres -d target_database
Método 2: Usar c (Connect) dentro de psql
Este es el método más práctico para el trabajo interactivo. El metacomando c cierra la conexión actual y abre una nueva a la base de datos especificada — todo dentro de la misma sesión de terminal.
c target_database
También puede cambiar de usuario y host simultáneamente:
c target_database admin_user localhost 5432
Sintaxis: c [database [username [host [port]]]]Cuando ejecuta c, psql mostrará una confirmación:
You are now connected to database "target_database" as user "postgres".Caso límite importante: Si la base de datos de destino no existe o el usuario actual carece del privilegio CONNECT, c fallará y lo devolverá a la conexión anterior. Esto es más seguro de lo que parece — no quedará sin conexión, pero debe manejar esto en los scripts verificando el estado de salida.
Método 3: Conectarse como un usuario diferente
Para conectarse a una base de datos bajo un rol específico:
psql -d myapp_db -U appuser -h localhost -p 5432O usando el atajo c dentro de una sesión existente:
c myapp_db appuserEsto es particularmente útil al probar políticas de seguridad a nivel de fila (RLS) o verificar que los usuarios de la aplicación no puedan acceder a tablas fuera de su esquema.
Método 4: Usar cadenas de conexión (formato URI)
PostgreSQL admite el formato de URI de conexión libpq, que encapsula todos los parámetros de conexión en una sola cadena. Este es el método preferido para la configuración de aplicaciones, canalizaciones CI/CD y herramientas de infraestructura como código.
psql "postgresql://appuser:password@localhost:5432/myapp_db"O usando el esquema postgres:// (ambos son válidos):
psql "postgres://appuser:password@db.example.com:5432/analytics?sslmode=require"El parámetro ?sslmode=require impone el cifrado TLS en la conexión — un requisito innegociable para cualquier base de datos expuesta más allá del localhost. Si está alojando PostgreSQL en un VPS o servidor dedicado, siempre combine las cadenas de conexión con sslmode=require o sslmode=verify-full y un certificado SSL válido.
Parámetros de URI de conexión a destacar:
| Parámetro | Propósito | Valor de ejemplo |
|---|---|---|
sslmode | Nivel de imposición de TLS | require, verify-full |
connect_timeout | Segundos antes de que falle la conexión | 10 |
application_name | Identifica al cliente en pg_stat_activity | myapp_worker |
options | Pasar parámetros GUC del lado del servidor | -c search_path=myschema |
Método 5: Usar psql con variables de entorno
Para conexiones repetidas al mismo clúster, establezca variables de entorno para evitar escribir credenciales repetidamente:
export PGHOST=localhost
export PGPORT=5432
export PGUSER=postgres
export PGPASSWORD=secret # Use .pgpass file in production instead
export PGDATABASE=myapp_db
psqlEn producción, use un archivo .pgpass en lugar de PGPASSWORD para evitar exponer credenciales en el historial del shell o en las listas de procesos:
# ~/.pgpass format: hostname:port:database:username:password
localhost:5432:myapp_db:appuser:strongpasswordConfigure los permisos correctamente o PostgreSQL ignorará el archivo:
chmod 600 ~/.pgpassComparación: métodos de cambio de base de datos
| Método | Contexto | Requiere nuevo proceso | Admite cambio de usuario | Scriptable |
|---|---|---|---|---|
q + psql -d | Shell | Sí | Sí | Sí |
c dbname | psql interactivo | No (psql lo gestiona) | Sí | Limitado |
| URI de conexión | Shell / Aplicación | Sí | Sí | Sí |
| Variables de entorno | Shell | Sí | Sí | Sí |
| pgAdmin GUI | Cliente GUI | No | Sí | No |
| Pooler de conexiones (PgBouncer) | Aplicación | No | Depende del modo | Sí |
Gestionar múltiples conexiones de base de datos de manera eficiente
Usar pgAdmin para la navegación basada en GUI
pgAdmin lista todas las bases de datos bajo cada servidor registrado en el árbol de objetos del lado izquierdo. Al hacer clic en una base de datos y abrir la herramienta de consultas, todas las consultas se limitan automáticamente a esa base de datos. Esto es útil para trabajo exploratorio, pero no es adecuado para la automatización.
Inconveniente: pgAdmin mantiene ranuras de conexión separadas por base de datos. Si su servidor PostgreSQL tiene una configuración baja de max_connections (el valor predeterminado es 100), abrir muchas bases de datos en pgAdmin puede agotar el grupo de conexiones antes de que su aplicación siquiera inicie.
Usar PgBouncer para la agrupación de conexiones
En entornos de producción con cambios frecuentes de base de datos, un pooler de conexiones como PgBouncer reduce drásticamente la sobrecarga. PgBouncer opera en tres modos:
- Modo sesión: Una conexión de servidor por sesión de cliente. Funcionalmente equivalente a las conexiones directas.
- Modo transacción: La conexión del servidor se mantiene solo durante una transacción. El más eficiente para cargas de trabajo OLTP.
- Modo sentencia: La conexión se devuelve después de cada sentencia. Incompatible con transacciones de múltiples sentencias.
Cuando se ejecutan múltiples bases de datos de aplicaciones en una única instancia de PostgreSQL — un patrón común en hosting VPS o VPS con cPanel — PgBouncer en modo transacción puede reducir los procesos backend activos en un orden de magnitud.
Consultas entre bases de datos con dblink y postgres_fdw
Dado que las sesiones están limitadas a una base de datos, consultar datos entre bases de datos requiere una extensión. PostgreSQL ofrece dos opciones:
dblink — enfoque más antiguo y procedimental:
SELECT * FROM dblink(
'dbname=analytics user=analyst host=localhost',
'SELECT user_id, event_count FROM events WHERE date = current_date'
) AS remote(user_id INT, event_count BIGINT);postgres_fdw — Foreign Data Wrapper moderno y compatible con estándares:
CREATE EXTENSION postgres_fdw;
CREATE SERVER analytics_server
FOREIGN DATA WRAPPER postgres_fdw
OPTIONS (host 'localhost', dbname 'analytics', port '5432');
CREATE USER MAPPING FOR appuser
SERVER analytics_server
OPTIONS (user 'analyst', password 'secret');
CREATE FOREIGN TABLE remote_events (
user_id INT,
event_count BIGINT
)
SERVER analytics_server
OPTIONS (schema_name 'public', table_name 'events');Después de la configuración, remote_events se comporta como una tabla local. postgres_fdw admite la transferencia de predicados, lo que significa que las cláusulas WHERE se ejecutan en el servidor remoto, no localmente — una distinción de rendimiento crítica para conjuntos de datos grandes.
Bases de datos del sistema: lo que no debe tocar
PostgreSQL incluye cuatro bases de datos en cada clúster nuevo:
| Base de datos | Propósito | ¿Seguro para conectarse? | ¿Seguro para modificar? |
|---|---|---|---|
postgres | Base de datos de administración predeterminada | Sí | Con precaución |
template1 | Plantilla para CREATE DATABASE | Sí | Sí, los cambios se propagan |
template0 | Plantilla de referencia limpia | Raramente | No |
pg_catalog | No es una base de datos, es un esquema | N/A | Nunca |
template1 se clona cada vez que ejecuta CREATE DATABASE sin especificar una plantilla. Si instala extensiones o crea esquemas en template1, cada nueva base de datos los heredará. Esto es útil para estandarizar entornos, pero peligroso si se hace accidentalmente.
template0 existe como respaldo intacto. Es la única plantilla que se puede usar al restaurar un archivo pg_dump con una codificación o configuración regional diferente, porque no tiene objetos creados por el usuario que puedan generar conflictos.
Privilegios, pg_hba.conf y fallos de conexión
Una fuente común de confusión al cambiar de base de datos es la distinción entre los privilegios a nivel de rol de PostgreSQL y las reglas de autenticación de pg_hba.conf. Ambos deben permitir la conexión de forma independiente.
Verificación a nivel de rol: El rol debe tener el privilegio CONNECT sobre la base de datos de destino:
GRANT CONNECT ON DATABASE target_database TO appuser;Verificación de pg_hba.conf: El archivo de autenticación basada en host (/etc/postgresql/15/main/pg_hba.conf en Debian/Ubuntu) debe tener una regla coincidente para el usuario, la base de datos y la dirección de origen. Una entrada típica:
# TYPE DATABASE USER ADDRESS METHOD
host myapp_db appuser 10.0.0.0/8 scram-sha-256Después de editar pg_hba.conf, recargue la configuración sin reiniciar el servidor:
sudo systemctl reload postgresqlO desde dentro de psql:
SELECT pg_reload_conf();Patrón de fallo común: Un usuario tiene el privilegio CONNECT a nivel SQL, pero pg_hba.conf no tiene ninguna regla coincidente. El mensaje de error (FATAL: no pg_hba.conf entry for host) es explícito, pero los desarrolladores a menudo pasan por alto el archivo por completo porque esperan que los permisos de la base de datos se gestionen únicamente a través de SQL.
Matriz de decisión práctica
Use esta lista de verificación para seleccionar el enfoque de conexión adecuado para su escenario:
- Exploración interactiva en una máquina de desarrollo local: Use
c dbnamedentro depsql. Rápido, sin nuevo proceso. - Script de shell que itera sobre múltiples bases de datos: Use
psql -U postgres -d $dbname -c "..."en un bucle con-t -Apara una salida limpia. - Aplicación que se conecta a una base de datos: Use una URI de conexión con
sslmode=requirey un grupo de conexiones (PgBouncer o agrupación integrada del controlador). - Aplicación que necesita datos de dos bases de datos: Implemente
postgres_fdwen la base de datos principal en lugar de gestionar dos grupos de conexiones separados en el código de la aplicación. - Verificación de RLS o aislamiento de privilegios: Use
c dbname role_namepara suplantar el rol de destino sin salir depsql. - Aprovisionamiento automatizado / infraestructura como código: Use variables de entorno o
.pgpasscon una cuenta de servicio; nunca codifique credenciales en scripts. - Carga de trabajo de producción de alta concurrencia: Implemente PgBouncer en modo transacción entre la aplicación y PostgreSQL. En un servidor dedicado, ajuste
max_connectionsenpostgresql.confpara que coincida con la capacidad de memoria RAM de su hardware (cada backend usa aproximadamente 5–10 MB de RAM). - SaaS multitenant con bases de datos por tenant: Considere la multitenencia basada en esquemas dentro de una única base de datos en lugar de bases de datos por tenant, para evitar la fragmentación del grupo de conexiones y simplificar las estrategias de respaldo.
Para los equipos que ejecutan PostgreSQL junto con aplicaciones web, combinar el servidor de base de datos con un entorno de hosting compartido o VPS correctamente configurado y un dominio registrado para la capa de aplicación completa la pila de producción estándar.
Preguntas frecuentes
¿Puedo cambiar de base de datos sin cerrar mi sesión de psql?
Sí. Use el metacomando c target_database dentro de psql. Cierra la conexión backend actual y abre una nueva a la base de datos especificada, todo dentro de la misma sesión de terminal. Opcionalmente puede especificar un usuario, host y puerto diferentes en el mismo comando.
¿Por qué PostgreSQL no tiene un comando USE como MySQL?
La arquitectura de PostgreSQL vincula un proceso backend a una única base de datos al inicio. El catálogo del sistema de la base de datos se carga en la memoria compartida para ese proceso, y cambiar de catálogo a mitad de sesión es arquitectónicamente equivalente a iniciar un nuevo proceso. El comando c en psql es el equivalente práctico — simplemente hace que el reinicio del proceso sea transparente para el usuario.
¿Cómo consulto datos de dos bases de datos PostgreSQL diferentes simultáneamente?
Use la extensión postgres_fdw para crear un servidor externo y tablas externas que se mapeen a la base de datos remota. Después de la configuración, puede hacer JOIN entre tablas locales y remotas en una sola consulta. Para consultas puntuales, dblink es más simple pero menos eficiente y más difícil de mantener.
¿Qué sucede si me conecto a template1 y la modifico?
Cualquier objeto que cree en template1 — tablas, extensiones, esquemas — se clonará en cada nueva base de datos creada con CREATE DATABASE (a menos que se especifique explícitamente TEMPLATE template0). Esto a veces es intencional (por ejemplo, preinstalar uuid-ossp o pgcrypto), pero las modificaciones accidentales pueden corromper todas las bases de datos creadas posteriormente.
¿Cómo encuentro a qué base de datos está conectada la sesión actual de psql?
Ejecute lo siguiente dentro de psql:
SELECT current_database();O verifique el propio indicador de psql — por defecto muestra dbname=# (superusuario) o dbname=> (usuario regular), donde dbname es la base de datos activa.
