PostgreSQL 테이블 이름을 사용할 수 없습니다 (“관계가 존재하지 않습니다”)


183

간단한 데이터베이스 쿼리를 수행하기 위해 다음 PHP 스크립트를 실행하려고합니다.

$db_host = "localhost";
$db_name = "showfinder";
$username = "user";
$password = "password";
$dbconn = pg_connect("host=$db_host dbname=$db_name user=$username password=$password")
    or die('Could not connect: ' . pg_last_error());

$query = 'SELECT * FROM sf_bands LIMIT 10';
$result = pg_query($query) or die('Query failed: ' . pg_last_error());

다음과 같은 오류가 발생합니다.

쿼리 실패 : 오류 : "sf_bands"관계가 없습니다

모든 예제에서 관계가 존재하지 않는다는 오류가 발생하는 위치를 찾을 수 있습니다. 테이블 이름에 대문자를 사용하기 때문입니다. 내 테이블 이름에 대문자가 없습니다. 데이터베이스 이름을 포함하지 않고 테이블을 쿼리하는 방법이 showfinder.sf_bands있습니까?


2
sf_bands 테이블이 존재합니까? showfinder.sf_bands가 작동합니까?
brian-brazil

1
showfinder.sf_bands는 완벽하게 작동
Keyslinger

아마도 내 데이터베이스가 MySQL에서 마이그레이션되었다는 사실에 주목해야 할 것입니다.
Keyslinger

pg_query ($ dbconn, $ query) 시도해 볼 수 있습니까? 암시 적 연결은 디버그하기 어려운 문제를 일으킬 수 있으며 가능한 문제를 제거 할 수도 있습니다. pg_dbname ($ dbconn)을 사용해 실제로 파인더에 연결되어 있는지 확인할 수 있습니까?
brian-brazil

1
대문자가 문제라고 언급하면 ​​+1입니다. PostgreSQL의 단일 테이블에서 선택할 수없는 이유를 알아 내려고 한 시간을 보냈습니다. 정말 끔찍한 프로그램입니다.
Brain2000

답변:


298

내가 읽은 것에서이 오류는 테이블 이름을 올바르게 참조하지 않았 음을 의미합니다. 일반적인 이유 중 하나는 테이블이 대소 문자를 혼합하여 정의되어 있고 모든 소문자를 사용하여 쿼리하려고하기 때문입니다.

다시 말해, 다음과 같은 경우 실패합니다.

CREATE TABLE "SF_Bands" ( ... );

SELECT * FROM sf_bands;  -- ERROR!

큰 따옴표를 사용하여 식별자를 구분하여 테이블이 정의 될 때 특정 대소 문자를 사용하는 맞춤법을 사용할 수 있습니다.

SELECT * FROM "SF_Bands";

주석을 다시 말해 "search_path"에 스키마를 추가하면 스키마를 규정하지 않고 테이블 이름을 참조 할 때 쿼리가 각 스키마를 순서대로 확인하여 해당 테이블 이름과 일치하게됩니다. PATH쉘이나 include_pathPHP 와 마찬가지로 현재 스키마 검색 경로를 확인할 수 있습니다.

SHOW search_path
  "$user",public

스키마 검색 경로를 변경할 수 있습니다.

SET search_path TO showfinder,public;

참조 http://www.postgresql.org/docs/8.3/static/ddl-schemas.html


죄송합니다. 내 테이블 이름에는 데이터베이스 이름이 아닌 대문자가 없습니다.
Keyslinger 2016 년

13
SELECT * FROM SF_BandsPostgres가 테이블 이름을 소문자로 결정하기 때문에 입력해도 여전히 실패한 것으로 보입니다 . 이상한 ...
로마 Starkov

3
@romkyns : 그렇습니다. 이는 RDBMS 브랜드에서 매우 흔하며, 구분되지 않은 식별자는 "대소 문자를 구분하지 않습니다"라고 광고됩니다. 그러나 구현 방식이 소문자를 강제하기 때문에 대소 문자를 구분하지 않습니다. 테이블을 정의 할 때 테이블 이름을 소문자로 허용 한 경우에만 테이블 이름과 일치합니다. CREATE TABLE을 사용할 때 큰 따옴표 구분 기호를 사용하는 경우 쿼리에서 구분 기호를 참조 할 때는 구분 기호를 사용해야합니다.
Bill Karwin

Postgres는 테이블 이름이 따옴표가 아닌 경우 자동으로 소문자입니까? 그것은 꽤 asinine입니다 ...
Andy

@Andy는 고유 한 SQL 데이터베이스를 작성할 때 대소 문자를 구분하지 않는 식별자를 다른 방법으로 구현할 수 있습니다. :)
Bill Karwin

76

나는 이것에 문제가 있었고 이것은 이야기입니다 (슬프지만 사실입니다) :

  1. 테이블 이름이 모두 소문자 : 계정과 같은 경우 사용할 수 있으며 다음 select * from AcCounTs과 같이 작동합니다.

  2. 테이블 이름이 모두 소문자 인 경우 accounts 다음이 실패합니다. select * from "AcCounTs"

  3. 테이블 이름이 대소 문자가 혼합 된 경우 Accounts 다음이 실패합니다. select * from accounts

  4. 테이블 이름이 대소 문자가 혼합 된 경우 : Accounts 다음은 정상적으로 작동합니다. select * from "Accounts"

나는 이런 쓸모없는 것들을 기억하는 것을 좋아하지 않지만 당신은;)해야합니다.


1
where-clauses의 열 이름과 동일
Roland

8
5. 같은 대소 문자는 가장 이상한 부분을 발견 Accounts하면 실패합니다 select * from Accounts;. 같은 경우는 동일하지 않습니다.
Roland

7
인용 부호를 사용하지 않는 한 postgres 쿼리의 모든 이름은 소문자입니다.
Erndob

1
PHP를 사용하지 않더라도 네 번째 옵션이 효과적이었습니다.
Sayari

2
모든 상호 작용을 준비해 주셔서 감사합니다! :)
GetHacked

16

다른 RDMS와 다른 Postgres 프로세스 쿼리 "SCHEMA_NAME"과 같이 테이블 이름 앞에 스키마 이름을 큰 따옴표로 묶으십시오. "SF_Bands"


7
귀하의 답변은 이전에 수락 된 답변에 22 번이나 자세한 내용을 추가하여 어떤 내용을 추가합니까?
Yaroslav

16

연결 문자열에 dbname 매개 변수를 넣으십시오. 다른 모든 것이 실패하는 동안 그것은 나를 위해 작동합니다.

또한 선택을 수행 할 때을 지정하십시오 your_schema. your_table이처럼 :

select * from my_schema.your_table

1
my_schema.my_relation과 같은 스키마 이름을 쿼리에 넣는 것이 도움이되었습니다.
JoeTidee

2
대단히 감사합니다! 그것은 문제를 해결하는 데 도움이됩니다! 그러나 체계 이름을 생략 할 수있는 방법이 있습니까?
Charlotte

8

OSX에서도 비슷한 문제가 있었지만 큰 따옴표와 작은 따옴표로 놀았습니다. 귀하의 경우 다음과 같은 것을 시도 할 수 있습니다

$query = 'SELECT * FROM "sf_bands"'; // NOTE: double quotes on "sf_Bands"

4

이것은 정말 도움이됩니다

SET search_path TO schema,public;

이 문제를 더 자세히 조사한 후 현재 데이터베이스의 새 사용자에 대해 defoult로이 "search_path"를 설정하는 방법에 대해 알아 냈습니다.

데이터베이스 속성을 연 다음 시트 "변수"를 열고 사용자를 위해이 변수를 실제 값으로 추가하십시오.

이제 사용자는 defoult를 통해이 schema_name을 가져오고 schemaName없이 tableName을 사용할 수 있습니다.


4

인용 부호로 스키마 이름과 테이블 이름을 작성해야합니다. 아래:

select * from "schemaName"."tableName";

1

나에게 문제는 장고가 초기화되는 동안 특정 테이블에 쿼리를 사용했다는 것입니다. 물론 해당 테이블이 없기 때문에 오류가 발생합니다. 필자의 경우 get_or_create소프트웨어가 어떤 종류의 작업 (이 경우 마이그레이션)을 실행할 때마다 실행되는 admin.py 파일 내의 방법이었습니다. 누군가에게 도움이되기를 바랍니다.


0

먼저 스키마를 추가해야합니다. 예 :

SELECT * FROM place.user_place;

모든 쿼리에 추가하지 않으려면 다음을 시도하십시오.

SET search_path TO place;

이제 작동합니다 :

SELECT * FROM user_place;

0

가장 쉬운 해결 방법은 테이블 이름과 모든 열 이름을 소문자로 변경하면 문제가 해결됩니다.

예를 들면 다음과 같습니다.

  • 변경 Table_Nametable_name 하고
  • 변경 ColumnNamecolumnname
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.