programing

Postgre에 데이터베이스가 있는지 확인합니다.셸을 사용한 SQL

telebox 2023. 5. 12. 22:04
반응형

Postgre에 데이터베이스가 있는지 확인합니다.셸을 사용한 SQL

저는 누가 제게 포스트그레를 확인하기 위해 셸을 사용하는 것이 가능한지에 대해 말해줄 수 있는지 궁금합니다.SQL 데이터베이스가 있습니까?

나는 셸 스크립트를 만들고 있는데 데이터베이스가 아직 존재하지 않지만 지금까지 구현 방법을 볼 수 없는 경우에만 데이터베이스를 생성하기를 원합니다.

노트/업데이트(2021):대답은 효과가 있지만, 철학적으로 저는 포스그레스에게 질문하는 이 올바른 방법이라는 다른 의견에 동의합니다.

다음과 같은 다른 답변이 있는지 확인합니다.psql -c또는--command그 안에는 사용 사례에 더 적합합니다(예: Nicholas Gilly's, Nathan Osman's, Bruce's 또는 Pedro's 변형).


나는 Arturo의 솔루션을 다음과 같이 수정했습니다.

psql -lqt | cut -d \| -f 1 | grep -qw <db_name>


기능

psql -l다음과 같은 것을 출력합니다.

                                        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)

단순 접근 방식을 사용하면 "목록, "액세스" 또는 "행"이라는 데이터베이스를 검색할 수 있습니다.따라서 이 출력을 여러 개의 기본 명령줄 도구를 통해 파이프로 연결하여 첫 번째 열에서만 검색합니다.


-t합니다.

 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

그다에음.cut -d \| -f 1를 기준으로 출력을 나눕니다.|문자(백슬래시가 있는 셸에서 삭제)를 선택하고 필드 1을 선택합니다.이것은 다음과 같습니다.

 my_db             
 postgres          
 template0         
                   
 template1         
         

grep -w단어와 시 temp이 경우에는-q를하여 를 제외할 수 있습니다.-q그래서 무언가가 즉시 표시됩니다.

:grep -w는 영숫자, 숫자 및 밑줄과 일치합니다. 이는 postgresql의 따옴표로 묶이지 않은 데이터베이스 이름에 사용할 수 있는 문자 집합입니다(따옴표로 묶이지 않은 식별자에서는 하이픈을 사용할 수 없습니다).만당신다캐른사있다면고용하를릭터를 사용한다면,grep -w당신한테는 안 통할 겁니다.


이 전체 파이프라인의 종료 상태는 다음과 같습니다.0 또는 (success) 데이터베이스가 존재하는 경우1만약 그렇지 않다면요.의 셸은 한 변수를 입니다.$?마지막 명령의 종료 상태로 이동합니다.조건부로 상태를 직접 테스트할 수도 있습니다.

if psql -lqt | cut -d \| -f 1 | grep -qw <db_name>; then
    # database exists
    # $? is 0
else
    # ruh-roh
    # $? is 1
fi

다음 셸 코드가 저에게 적합한 것 같습니다.

if [ "$( psql -XtAc "SELECT 1 FROM pg_database WHERE datname='DB_NAME'" )" = '1' ]
then
    echo "Database already exists"
else
    echo "Database does not exist"
fi

에대 도른말에 psql위에 주어진 플래그:

General options:
  -c, --command=COMMAND    run only single command (SQL or internal) and exit
  -X, --no-psqlrc          do not read startup file (~/.psqlrc)

Output format options:
  -A, --no-align           unaligned table output mode
  -t, --tuples-only        print rows only
postgres@desktop:~$ psql -l | grep <exact_dbname> | wc -l

지정한 데이터베이스가 있으면 1을 반환하고 지정하지 않으면 0을 반환합니다.

또한 이미 존재하는 데이터베이스를 생성하려고 하면 postgresql이 다음과 같은 오류 메시지를 반환합니다.

postgres@desktop:~$ createdb template1
createdb: database creation failed: ERROR:  database "template1" already exists

postgresql은 처음이지만 다음 명령은 데이터베이스가 있는지 확인하기 위해 사용한 것입니다.

if psql ${DB_NAME} -c '\q' 2>&1; then
   echo "database ${DB_NAME} exists"
fi

데이터베이스가 없는 경우 다음 방법을 사용하여 데이터베이스를 작성할 수 있습니다.

if [[ -z `psql -Atqc '\list mydatabase' postgres` ]]; then createdb mydatabase; fi

저는 간결하고 POSIX 호환 양식에 대한 다른 답변을 결합하고 있습니다.

psql -lqtA | grep -q "^$DB_NAME|"

의 반환true(0)는 존재함을 의미합니다.

데이터베이스 이름에 다음과 같은 비표준 문자가 있을 수 있다고 의심되는 경우$조금 더 긴 접근 방식이 필요합니다.

psql -lqtA | cut -d\| -f1 | grep -qxF "$DB_NAME"

-t그리고.-A옵션을 사용하면 출력이 "표형" 또는 공백으로 구분된 출력이 아닌 원시 출력인지 확인할 수 있습니다.열은 파이프 문자로 구분됩니다.|그래서 어느 쪽이든cut또는grep이것을 인식해야 합니다.첫 번째 열에는 데이터베이스 이름이 들어 있습니다.

편집: -x로 grep하면 이름이 부분적으로 일치하지 않습니다.

#!/bin/sh
DB_NAME=hahahahahahaha
psql -U postgres ${DB_NAME} --command="SELECT version();" >/dev/null 2>&1
RESULT=$?
echo DATABASE=${DB_NAME} RESULT=${RESULT}
#

완전성을 위해 문자열 자르기 대신 정규식을 사용하는 다른 버전:

psql -l | grep '^ exact_dbname\b'

예를 들어, 다음과 같습니다.

if psql -l | grep '^ mydatabase\b' > /dev/null ; then
  echo "Database exists already."
  exit
fi

다른 솔루션(훌륭한 솔루션)은 psql이 호스트에 연결할 수 없는 경우 시간 초과하기 전에 1분 이상 기다릴 수 있다는 사실을 간과하고 있습니다.시간 초과를 3초로 설정하는 이 솔루션이 좋습니다.

PGCONNECT_TIMEOUT=3 psql development -h db -U postgres -c ""

이것은 공식 포스트그레스 알파인 도커 이미지의 개발 데이터베이스에 연결하기 위한 것입니다.

이와는 별도로 레일즈를 사용하고 있으며 데이터베이스가 아직 존재하지 않는 경우(도커 컨테이너를 시작할 때처럼), 마이그레이션이 동일하기 때문에 잘 작동합니다.

bundle exec rake db:migrate 2>/dev/null || bundle exec rake db:setup

키부의 받아들여진 대답은 결함이 있습니다.grep -w지정한 패턴을 단어 구성 요소로 포함하는 모든 이름과 일치합니다.

예를 들어, "foo"를 찾는다면 "foo-backup"이 일치합니다.

Othetus의 답변은 몇 가지 좋은 개선 사항을 제공하며 짧은 버전은 대부분의 경우에 올바르게 작동하지만 제공되는 두 변형 중 더 긴 버전은 일치하는 하위 문자열과 유사한 문제를 나타냅니다.

이 문제를 해결하기 위해 POSIX를 사용할 수 있습니다.-x텍스트의 전체 행만 일치시키는 인수입니다.

Otheus의 답변을 바탕으로 새로운 버전은 다음과 같습니다.

psql -U "$USER" -lqtA | cut -d\| -f1 | grep -qFx "$DBNAME"

이 모든 것이 말해주듯이, 저는 니콜라스 그릴리의 대답이 - 구체적인 데이터베이스에 대해 실제로 포스트게스트들에게 질문하는 - 모든 것들 중에서 가장 좋은 접근법이라고 말하고 싶습니다.

psql -l|awk '{print $1}'|grep -w <database>

더 짧은 버전

저는 아직 셸 프로그래밍에 대해 꽤 경험이 부족합니다. 만약 이것이 어떤 이유에서 정말로 잘못되었다면, 저를 부결시키십시오. 하지만 너무 놀라지 마십시오.

키부의 답변을 토대로 구축:

# 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

은 이명령호데스수이반다를니라고 하는 합니다.DATABASE_NAME:psql -At -U postgres -c "select count(*) from pg_databases where datname = 'DATABASE_NAME';

그렇게

if [ "$(psql -At -U postgres -c "select count(*) from pg_databases where datname = 'DATABASE_NAME`;")" -eq 0 ] ; then
   # This runs if the DB doesn't exist.
fi
  • 한 줄로:

PGPASSWORD=mypassword psql -U postgres@hostname -h postgres.hostname.com -tAc 'select 1' -d dbnae || echo 0

DB가 0인 경우 1을 반환합니다. 그렇지 않은 경우 0을 반환합니다.

  • 또는 더 읽기 쉬운 것:
if [ "$(PGPASSWORD=mypassword psql -U postgres@hostname -h postgres.hostname.com -tAc 'select 1' -d dbnae || echo 0 )" = '1' ]
then
    echo "Database already exists"
else
    echo "Database does not exist"
fi

존재하지 않는 경우 0으로 나눗셈을 트리거한 후 다음과 같은 반환 코드를 확인합니다.

sql="SELECT 1/count(*) FROM pg_database WHERE datname='db_name'";
error=$(psql -h host -U user -c "$sql" postgres);
if $error
then
  echo "doesn't exist";
else
  echo "exists";
fi

언급URL : https://stackoverflow.com/questions/14549270/check-if-database-exists-in-postgresql-using-shell

반응형