Имитировать создание базы данных, если она не существует для PostgreSQL?
Я хочу создать базу данных, которая не существует через JDBC. В отличие от MySQL, PostgreSQL не поддерживает create if not exists синтаксис. Каков наилучший способ добиться этого?
приложение не знает, существует ли база данных или нет. Он должен проверить, и если база данных существует, она должна быть использована. Поэтому имеет смысл подключиться к нужной базе данных, и если соединение не удается из-за отсутствия базы данных, он должен создать новую базу данных (путем подключения к умолчанию postgres база данных.) Я проверил код ошибки, возвращенный Postgres, но я не смог найти никакого соответствующего кода, который бы выглядел одинаково.
еще один способ добиться этого - подключиться к postgres база данных и проверьте, существует ли нужная база данных, и примите соответствующие меры. Второй немного утомительно работать.
есть ли способ достичь этой функциональности в Postgres?
3 ответов:
вы можете спросить системный каталог. Хитрая часть (как было прокомментировано), что
CREATE DATABASEможет выполняться только как один оператор. в документации:
CREATE DATABASEневозможно выполнить внутри блока транзакций.поэтому он не может быть запущен внутри функции или
DOоператор, где он будет находиться внутри блока транзакций неявно. Это можно обойти, хотя с помощьюdblinkподключение к текущая база данных, которая работает вне блока транзакций. Поэтому эффекты также не могут быть откатаны.вам необходимо установить дополнительный модуль dblink (один раз на дБ):
затем:
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$;подробное объяснение того, как это работает:
протестировано с Postgres 9.3. Вы можете сделать эту функцию для повторного использования.
еще одна альтернатива, на всякий случай вы хотите иметь сценарий оболочки, который создает базу данных, если она не существует, а в противном случае просто сохраняет ее как есть:
psql -U postgres -tc "SELECT 1 FROM pg_database WHERE datname = 'my_db'" | grep -q 1 || psql -U postgres -c "CREATE DATABASE my_db"Я нашел это полезным в сценариях подготовки devops, которые вы можете запускать несколько раз на одном экземпляре.
мне пришлось использовать немного расширенную версию @Erwin Brandstetter used:
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$Я должен был включить
dblinkрасширение, плюс я должен был предоставить учетные данные для dblink. Работает с Postgres 9.4.
Comments