184 votes

Simuler CREATE DATABASE IF NOT EXISTS pour PostgreSQL ?

Je veux créer une base de données qui n'existe pas via JDBC. Contrairement à MySQL, PostgreSQL ne supporte pas create if not exists syntaxe. Quelle est la meilleure façon d'y parvenir ?

L'application ne sait pas si la base de données existe ou non. Elle doit vérifier et si la base de données existe, elle doit être utilisée. Il est donc logique de se connecter à la base de données souhaitée et si la connexion échoue en raison de l'inexistence de la base de données, elle doit créer une nouvelle base de données (en se connectant à la base de données par défaut postgres base de données). J'ai vérifié le code d'erreur renvoyé par Postgres mais je n'ai pas pu trouver de code pertinent de la même espèce.

Une autre méthode pour y parvenir consisterait à se connecter à l'application postgres et vérifier si la base de données souhaitée existe et prendre des mesures en conséquence. La seconde est un peu fastidieuse à mettre en œuvre.

Existe-t-il un moyen de réaliser cette fonctionnalité dans Postgres ?

5voto

wener Points 497

Si vous pouvez utiliser le shell, essayez

psql -U postgres -c 'select 1' -d $DB &>dev/null || psql -U postgres -tc 'create database $DB'

Je pense psql -U postgres -c "select 1" -d $DB est plus facile que SELECT 1 FROM pg_database WHERE datname = 'my_db' et n'ont besoin que d'un seul type de devis, plus facile à combiner avec les services suivants sh -c .

J'utilise ceci dans ma tâche ansible

- name: create service database
  shell: docker exec postgres sh -c '{ psql -U postgres -tc "SELECT 1" -d {{service_name}} &> /dev/null && echo -n 1; } || { psql -U postgres -c "CREATE DATABASE {{service_name}}"}'
  register: shell_result
  changed_when: "shell_result.stdout != '1'"

1voto

Ahmet Emrebas Points 61

Le meilleur moyen est d'exécuter le SQL.

CREATE DATABASE MY_DATABASE; 

si la base de données existe déjà, il jette "database already exists error" ce qui vous permet de faire ce que vous voulez, sinon il crée la base de données. Je ne pense pas qu'il créera une nouvelle base de données par-dessus la vôtre :D

0voto

Vincent Gerris Points 925

Après avoir lu toutes ces solutions, à mon avis compliquées, qui ne sont que des contournements terribles de l'absence de l'option IF NOT EXIST pour la création d'un utilisateur postgres, j'ai oublié qu'il existe un moyen simple de gérer cela au niveau du shell. Même si ce n'est pas ce que certains veulent, je pense que beaucoup de gens veulent de la simplicité et ne veulent pas créer des procédures et des constructions compliquées.

J'utilise docker, voici les extraits importants de mon bash script qui charge les données dans un devsetup :

execute_psql_command_pipe () {
         $DOCKER_COMMAND exec -it $POSTGRES_CONTAINER bash -c "echo \"$1\"| psql -h localhost -U postgres || echo psql command failed - object likely exists"
}

read -r -d '' CREATE_USER_COMMANDS << EOM
create user User1 WITH PASSWORD 'password';
create user User2 WITH PASSWORD 'password';
EOM

execute_psql_command_pipe "$CREATE_USER_COMMANDS"

Il y a quelques choses qui ne vont pas, mais c'est le moyen le plus simple que j'ai pu trouver pour lui faire faire ce que je veux : créer au premier passage du script, continuer au second passage quand il existe. Au fait, la sortie de l'écho ne s'affiche pas, mais les commandes continuent parce que la commande écho sort avec 0.

La même chose peut être faite pour toute commande (comme db create). Cela échoue évidemment (ou réussit, selon le point de vue) pour toute autre erreur qui peut se produire aussi, mais vous obtenez l'imprimante de sortie psql, de sorte que plus de traitement peut être ajouté.

-2voto

James Wierzba Points 5885

Il suffit de créer la base de données en utilisant createdb Outil CLI :

PGHOST="my.database.domain.com"
PGUSER="postgres"
PGDB="mydb"
createdb -h $PGHOST -p $PGPORT -U $PGUSER $PGDB

Si la base de données existe, elle renverra une erreur :

createdb: database creation failed: ERROR:  database "mydb" already exists

-2voto

Renato Damas Points 308

Une façon simple et propre de le faire que j'ai fini par utiliser :

createdb $DATABASE 2> /dev/null || echo "database already exists"

Si vous attendez une autre erreur que database "x" already exists qui, de toute évidence, ne fonctionnera pas (par exemple, permission refusée). Quoi qu'il en soit, si cela vous préoccupe, vous pouvez toujours effectuer ces vérifications avant ce point.

N'oubliez pas de définir la valeur de DATABASE et de passer dans les commutateurs requis pour l'accès à l'UE. createdb commandement. De préférence, vous pouvez aussi faire comme :

export PGHOST=localhost
export PGUSER=user
export PGPASSWORD=p455w0rd
...

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X