Symulować tworzenie bazy danych, jeśli nie istnieje dla PostgreSQL?
Chcę utworzyć bazę danych, która nie istnieje poprzez JDBC. W przeciwieństwie do MySQL, PostgreSQL nie obsługuje składni create if not exists
. Jaki jest najlepszy sposób, aby to osiągnąć?
Aplikacja nie wie, czy baza danych istnieje, czy nie. Powinien sprawdzić i czy baza danych istnieje powinna być użyta. Dlatego warto połączyć się z żądaną bazą danych i jeśli połączenie nie powiedzie się z powodu braku bazy danych, należy utworzyć nową bazę danych (łącząc się z domyślną bazą postgres
). I sprawdziłem kod błędu zwrócony przez Postgres, ale nie mogłem znaleźć żadnego odpowiedniego kodu, który byłby taki sam.
Inną metodą, aby to osiągnąć, byłoby połączenie się z bazą danych postgres
i sprawdzenie, czy żądana baza danych istnieje i podjęcie odpowiednich działań. Drugi jest trochę nudny do wypracowania.
Czy Jest jakiś sposób na osiągnięcie tej funkcjonalności w Postgres?
3 answers
Możesz zapytać katalog systemu. Najtrudniejsze jest to, że CREATE DATABASE
może być wykonywane tylko jako pojedyncza Instrukcja. wg dokumentacji:
CREATE DATABASE
nie można wykonać wewnątrz bloku transakcji.
Więc nie można go uruchomić wewnątrz funkcji lub DO
oświadczenie, gdzie znajduje się wewnątrz bloku transakcji bezwarunkowo. Można to jednak obejść, korzystając z połączenia dblink
z powrotem do bieżącej bazy danych, która działa poza blok transakcji. Efekty nie mogą być zatem wycofane.
Należy zainstalować dodatkowy moduł dblink (raz na db):
Potem:
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$;
Szczegółowe wyjaśnienie, jak to działa:
Testowane Z Postgres 9.3. Możesz zrobić z tego funkcję wielokrotnego użytku.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:45
Inna alternatywa, na wypadek, gdybyś chciał mieć skrypt powłoki, który tworzy bazę danych, jeśli nie istnieje, a w przeciwnym razie zachowuje ją taką, jaka jest:
psql -U postgres -tc "SELECT 1 FROM pg_database WHERE datname = 'my_db'" | grep -q 1 || psql -U postgres -c "CREATE DATABASE my_db"
Okazało się, że jest to pomocne w skryptach aprowizacyjnych devops, które można uruchamiać wiele razy na tej samej instancji.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-13 07:47:51
Musiałem użyć nieco rozszerzonej wersji @ Erwin Brandstetter używany:
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$
Musiałem włączyć rozszerzenie dblink
, dodatkowo musiałem podać dane uwierzytelniające dla dblink.
Współpracuje z Postgres 9.4.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-17 16:19:09