Simuler créer une base de données si elle N'existe pas pour PostgreSQL?

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

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

une autre méthode pour y parvenir serait de se connecter à la base de données postgres et de vérifier si la base de données désirée existe et de prendre des mesures en conséquence. Le second est un peu fastidieux.

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

66
demandé sur Erwin Brandstetter 2013-08-22 23:21:08

3 réponses

vous pouvez demander au catalogue système. La partie délicate est (comme cela a été commenté) que CREATE DATABASE ne peut être exécuté qu'en tant que simple instruction. par documentation:

CREATE DATABASE ne peut pas être exécuté à l'intérieur d'un bloc de transactions.

de sorte qu'il ne peut pas être exécuté à l'intérieur d'une fonction ou DO déclaration, où il serait implicitement à l'intérieur d'un bloc de transaction. Que peut être contourné en utilisant une connexion dblink de retour à la base de données actuelle, qui court en dehors du bloc de transaction. Les effets ne peuvent donc pas non plus être retranchés.

vous devez installer le module supplémentaire dblink (une fois par db):

puis:

DO
$do$
BEGIN
   IF EXISTS (SELECT 1 FROM pg_database WHERE datname = 'mydb') THEN
      RAISE NOTICE 'Database already exists'; 
   ELSE
      PERFORM dblink_exec('dbname=' || current_database()  -- current db
                        , 'CREATE DATABASE mydb');
   END IF;
END
$do$;

détail explication du fonctionnement:

Testé avec Postgres 9.3. Vous pourriez en faire une fonction pour une utilisation répétée.

47
répondu Erwin Brandstetter 2017-05-23 12:34:45

une autre alternative, juste au cas où vous voulez avoir un script shell qui crée la base de données si elle n'existe pas et sinon la garde telle qu'elle est:

psql -U postgres -tc "SELECT 1 FROM pg_database WHERE datname = 'my_db'" | grep -q 1 || psql -U postgres -c "CREATE DATABASE my_db"

j'ai trouvé cela utile dans les scripts de provision de devops, que vous pourriez vouloir exécuter plusieurs fois sur la même instance.

85
répondu andreasl 2016-04-13 07:47:51

j'ai dû utiliser une version légèrement étendue @Erwin Brandstetter utilisé:

DO
$do$
DECLARE
  _db TEXT := 'some_db';
  _user TEXT := 'postgres_user';
  _password TEXT := 'password';
BEGIN
  CREATE EXTENSION IF NOT EXISTS dblink; -- enable extension 
  IF EXISTS (SELECT 1 FROM pg_database WHERE datname = _db) THEN
    RAISE NOTICE 'Database already exists';
  ELSE
    PERFORM dblink_connect('host=localhost user=' || _user || ' password=' || _password || ' dbname=' || current_database());
    PERFORM dblink_exec('CREATE DATABASE ' || _db);
  END IF;
END
$do$

je devais activer l'extension dblink , plus je devais fournir les justificatifs d'identité pour dblink. Fonctionne avec Postgres 9.4.

5
répondu Ortwin Angermeier 2018-09-17 16:19:09