Compruebe si la base de datos existe en PostgreSQL usando shell
Me preguntaba si alguien podría decirme si es posible usar shell para verificar si existe una base de datos PostgreSQL.
Estoy haciendo un script de shell y solo quiero que cree la base de datos si aún no existe pero hasta ahora no he podido ver cómo implementarla.
12 answers
Utilizo la siguiente modificación de la solución de Arturo:{[19]]}
psql -lqt | cut -d \| -f 1 | grep -qw <db_name>
Lo que hace
psql -l
salidas algo como lo siguiente:
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+-----------+----------+------------+------------+-----------------------
my_db | my_user | UTF8 | en_US.UTF8 | en_US.UTF8 |
postgres | postgres | LATIN1 | en_US | en_US |
template0 | postgres | LATIN1 | en_US | en_US | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | LATIN1 | en_US | en_US | =c/postgres +
| | | | | postgres=CTc/postgres
(4 rows)
Usar el enfoque ingenuo significa que la búsqueda de una base de datos llamada "List, "Access" o "rows" tendrá éxito. Así que canalizamos esta salida a través de un montón de herramientas de línea de comandos integradas para buscar solo en la primera columna.
La bandera -t
elimina los encabezados y pie de página:
my_db | my_user | UTF8 | en_US.UTF8 | en_US.UTF8 |
postgres | postgres | LATIN1 | en_US | en_US |
template0 | postgres | LATIN1 | en_US | en_US | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | LATIN1 | en_US | en_US | =c/postgres +
| | | | | postgres=CTc/postgres
El siguiente bit, cut -d \| -f 1
divide la salida por el carácter vertical pipe |
(escapado del shell con una barra invertida), y selecciona el campo 1. Esto deja:
my_db
postgres
template0
template1
grep -w
coincide con palabras enteras, por lo que no coincidirá si está buscando temp
en este escenario. La opción -q
suprime cualquier salida escrita en la pantalla, por lo que si desea ejecutar esto interactivamente en un símbolo del sistema, puede excluir -q
para que se muestre algo inmediatamente.
Tenga en cuenta que grep -w
coincide con caracteres alfanuméricos, dígitos y el subrayado, que es exactamente el conjunto de caracteres permitidos en los nombres de bases de datos sin comillas en postgresql (los guiones no son legales en los identificadores sin comillas). Si está utilizando otros caracteres, grep -w
no funcionará para usted.
El estado de salida de toda esta canalización será 0
(éxito) si la base de datos existe o 1
(error) si no lo hace. Su shell establecerá la variable especial $?
en el estado de salida de la última orden. También puede probar el estado directamente en un condicional:
if psql -lqt | cut -d \| -f 1 | grep -qw <db_name>; then
# database exists
# $? is 0
else
# ruh-roh
# $? is 1
fi
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-19 07:05:21
El siguiente código de shell parece funcionar para mí:
if [ "$( psql -tAc "SELECT 1 FROM pg_database WHERE datname='DB_NAME'" )" = '1' ]
then
echo "Database already exists"
else
echo "Database does not exist"
fi
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-21 14:01:45
postgres@desktop:~$ psql -l | grep <exact_dbname> | wc -l
Esto devolverá 1 si la base de datos especificada existe o 0 de lo contrario.
Además, si intenta crear una base de datos que ya existe, postgresql devolverá un mensaje de error como este:
postgres@desktop:~$ createdb template1
createdb: database creation failed: ERROR: database "template1" already exists
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-27 11:19:08
Soy nuevo en postgresql, pero el siguiente comando es lo que usé para comprobar si existe una base de datos
if psql ${DB_NAME} -c '\q' 2>&1; then
echo "database ${DB_NAME} exists"
fi
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-03-21 02:05:19
Estoy combinando las otras respuestas a una forma sucinta y compatible con POSIX:
psql -lqtA | grep -q "^$DB_NAME|"
Un retorno de true
(0
) significa que existe.
Si sospecha que el nombre de su base de datos puede tener un carácter no estándar como $
, necesita un enfoque un poco más largo:
psql -lqtA | cut -d\| -f1 | grep -qxF "$DB_NAME"
Las opciones -t
y -A
se aseguran de que la salida sea raw y no "tabular" o rellena con espacios en blanco. Las columnas están separadas por el carácter de tubería |
, por lo que el cut
o el grep
tiene que reconoce esto. La primera columna contiene el nombre de la base de datos.
EDIT: grep con-x para evitar coincidencias parciales de nombres.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-24 15:58:47
#!/bin/sh
DB_NAME=hahahahahahaha
psql -U postgres ${DB_NAME} --command="SELECT version();" >/dev/null 2>&1
RESULT=$?
echo DATABASE=${DB_NAME} RESULT=${RESULT}
#
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-27 16:18:14
Puede crear una base de datos, si aún no existe, utilizando este método:
if [[ -z `psql -Atqc '\list mydatabase' postgres` ]]; then createdb mydatabase; fi
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-09 09:12:30
Para completar, otra versión que usa expresiones regulares en lugar de cortar cadenas:
psql -l | grep '^ exact_dbname\b'
Por ejemplo:
if psql -l | grep '^ mydatabase\b' > /dev/null ; then
echo "Database exists already."
exit
fi
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-13 12:18:45
La respuesta aceptada de Kibibu es defectuosa en que grep -w
coincidirá con cualquier nombre que contenga el patrón especificado como un componente de palabra.
Es decir, si buscas "foo", entonces "foo-backup" es una coincidencia.
La respuesta de Otheus proporciona algunas buenas mejoras, y la versión corta funcionará correctamente para la mayoría de los casos, pero la más larga de las dos variantes ofrece un problema similar con subcadenas coincidentes.
Para resolver este problema, podemos usar el POSIX -x
argumento para coincidir solo con líneas completas del texto.
Basándose en la respuesta de Oteo, la nueva versión se ve así:
psql -U "$USER" -lqtA | cut -d\| -f1 | grep -qFx "$DBNAME"
Dicho todo, me inclino a decir que La respuesta de Nicolas Grilly where donde realmente le preguntas a postgres sobre la base de datos específica is es el mejor enfoque de todos.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 10:31:29
Todavía soy bastante inexperto con la programación de shell, así que si esto es realmente malo por alguna razón, votarme, pero no te alarmes demasiado.
Construyendo a partir de la respuesta de kibibu:
# If resulting string is not zero-length (not empty) then...
if [[ ! -z `psql -lqt | cut -d \| -f 1 | grep -w $DB_NAME` ]]; then
echo "Database $DB_NAME exists."
else
echo "No existing databases are named $DB_NAME."
fi
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-16 09:30:12
psql -l|awk '{print $1}'|grep -w <database>
Versión abreviada
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-08 10:23:30
Las otras soluciones (que son fantásticas) pierden el hecho de que psql puede esperar un minuto o más antes de agotarse si no puede conectarse a un host. Por lo tanto, me gusta esta solución, que establece el tiempo de espera a 3 segundos:
PGCONNECT_TIMEOUT=3 psql development -h db -U postgres -c ""
Esto es para conectarse a una base de datos de desarrollo en la imagen oficial postgres Alpine Docker.
Por separado, si está utilizando Rails y desea configurar una base de datos si aún no existe (como al lanzar un contenedor Docker), esto funciona bien, ya que las migraciones son idempotentes:
bundle exec rake db:migrate 2>/dev/null || bundle exec rake db:setup
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-27 05:10:53