Não é possível simplesmente usar o nome da tabela do PostgreSQL (“a relação não existe”)

183

Estou tentando executar o seguinte script PHP para fazer uma consulta simples ao banco de dados:

$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());

Isso produz o seguinte erro:

Falha na consulta: ERRO: a relação "sf_bands" não existe

Em todos os exemplos, posso encontrar onde alguém recebe um erro informando que a relação não existe, é porque eles usam letras maiúsculas no nome da tabela. O nome da minha tabela não possui letras maiúsculas. Existe uma maneira de consultar minha tabela sem incluir o nome do banco de dados, ou seja showfinder.sf_bands?

Keyslinger
fonte
2
Tem certeza de que a tabela sf_bands existe? Showfinder.sf_bands funciona?
brian-Brasil
1
showfinder.sf_bands funciona perfeitamente
Keyslinger
Talvez eu deva notar que meu banco de dados foi migrado do MySQL
Keyslinger
Você pode tentar pg_query ($ dbconn, $ query)? A conexão implícita pode causar problemas difíceis de depurar, além de eliminá-la como um possível problema. Você também pode tentar pg_dbname ($ dbconn) para garantir que esteja realmente conectado ao showfinder?
brian-brazil
1
+1 por mencionar que as letras maiúsculas são o problema. Passei uma hora tentando descobrir por que não consegui selecionar em uma única tabela no PostgreSQL. Que programa terrível.
Brain2000

Respostas:

298

Pelo que li, esse erro significa que você não está fazendo referência ao nome da tabela corretamente. Um motivo comum é que a tabela é definida com uma grafia maiúscula e minúscula e você está tentando consultá-la.

Em outras palavras, o seguinte falha:

CREATE TABLE "SF_Bands" ( ... );

SELECT * FROM sf_bands;  -- ERROR!

Use aspas duplas para delimitar identificadores, para que você possa usar a ortografia específica entre maiúsculas e minúsculas conforme a tabela é definida.

SELECT * FROM "SF_Bands";

No seu comentário, você pode adicionar um esquema ao "search_path" para que, quando você fizer referência a um nome de tabela sem qualificar seu esquema, a consulta corresponderá ao nome da tabela verificando cada esquema na ordem. Assim como PATHno shell ou include_pathno PHP, etc. Você pode verificar seu caminho de pesquisa de esquema atual:

SHOW search_path
  "$user",public

Você pode alterar o caminho de pesquisa do esquema:

SET search_path TO showfinder,public;

Veja também http://www.postgresql.org/docs/8.3/static/ddl-schemas.html

Bill Karwin
fonte
Opa, me perdoe. Eu quis dizer que o nome da minha tabela não tem letras maiúsculas, não o nome do meu banco de dados.
Keyslinger
13
Parece que mesmo se você digitar SELECT * FROM SF_Bandsisso ainda falhará, porque o Postgres decide minúscula o nome da tabela para você. Estranho ...
Roman Starkov 17/05
3
@romkyns: Sim, isso é bastante comum nas marcas RDBMS, pois identificadores não limitados são anunciados como "sem distinção entre maiúsculas e minúsculas". Mas eles não fazem distinção entre maiúsculas e minúsculas, porque a maneira como implementaram isso é forçar letras minúsculas. Isso corresponde ao nome da tabela somente se você tivesse permitido que o nome da tabela estivesse em minúsculas ao definir a tabela. Se você usar delimitadores de aspas duplas ao criar TABLE, deverá usar delimitadores quando fizer referência a ele em consultas.
Bill Karwin
O Postgres reduz automaticamente os nomes das tabelas em minúsculas, se não estiverem entre aspas? Isso é muito estúpido ...
Andy
@ Andy, quando você escreve seu próprio banco de dados SQL, sinta-se à vontade para implementar identificadores que não diferenciam maiúsculas de minúsculas. :)
Bill Karwin
76

Eu tive problemas com isso e esta é a história (triste, mas verdadeira):

  1. Se o nome da sua tabela estiver em letras minúsculas como: contas, você poderá usar: select * from AcCounTse funcionará bem

  2. Se o nome da sua tabela estiver em letras minúsculas, como: accounts O seguinte irá falhar: select * from "AcCounTs"

  3. Se o nome da sua tabela estiver misturado com maiúsculas e minúsculas, como: Accounts O seguinte irá falhar: select * from accounts

  4. Se o nome da sua tabela estiver misturado com maiúsculas e minúsculas, como: Accounts O seguinte funcionará OK: select * from "Accounts"

Eu não gosto de lembrar coisas inúteis como essa, mas você precisa;)

Mitzi
fonte
1
Mesmo para os nomes das colunas em Where-cláusulas
Roland
8
5. Caso misto, tipo Accounts, falhará com select * from Accounts;a parte mais estranha: o mesmo caso NÃO é idêntico.
Roland
7
Tudo o que existe: todos os nomes na consulta postgres são minúsculos, a menos que você use aspas.
Erndob
1
A quarta opção funcionou para mim, embora eu não estou usando PHP
Sayari
2
Obrigado por definir todas as interações! :)
GetHacked 26/08/19
16

O Postgres processa uma consulta diferente de outros RDMS. Coloque o nome do esquema entre aspas antes do nome da sua tabela, como "SCHEMA_NAME". "SF_Bands"

Ugur Artun
fonte
7
O que sua resposta adiciona à resposta aceita anteriormente, com 22 votos a favor e com muitos detalhes?
Yaroslav #
16

Coloque o parâmetro dbname na sua cadeia de conexão. Funciona para mim enquanto tudo falhou.

Além disso, ao fazer a seleção, especifique o your_schema. your_tablecomo isso:

select * from my_schema.your_table
JarosPL
fonte
1
Colocar o nome do esquema, por exemplo, my_schema.my_relation na consulta ajudou.
31415 JoeTidee
2
Muito obrigado! Reall me ajuda a resolver o problema! Mas existe uma maneira de omitir o nome do esquema?
26417 Charlotte
8

Eu tive um problema semelhante no OSX, mas tentei brincar com aspas duplas e simples. Para o seu caso, você pode tentar algo como isto

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

Isso é realmente útil

SET search_path TO schema,public;

Eu cavei mais esses problemas e descobri como definir esse "caminho_de_pesquisa" desativando um novo usuário no banco de dados atual.

Abra Propriedades do DataBase, abra a Planilha "Variáveis" e simplesmente adicione essa variável ao seu usuário com valor real.

Portanto, agora seu usuário receberá esse schema_name por desativação e você poderá usar tableName sem schemaName.

Alexander Kuzichkin
fonte
4

Você deve escrever o nome do esquema e o nome da tabela entre aspas. Como abaixo:

select * from "schemaName"."tableName";
kira
fonte
1

Para mim, o problema era que eu tinha usado uma consulta para essa tabela em particular enquanto o Django era inicializado. É claro que isso gerará um erro, porque essas tabelas não existiam. No meu caso, era um get_or_createmétodo dentro de um arquivo admin.py, executado sempre que o software executava qualquer tipo de operação (neste caso, a migração). Espero que ajude alguém.

Özer S.
fonte
0

Você deve adicionar o esquema primeiro, por exemplo

SELECT * FROM place.user_place;

Se você não deseja adicionar isso em todas as consultas, tente o seguinte:

SET search_path TO place;

Agora vai funcionar:

SELECT * FROM user_place;
Alexis Gamarra
fonte
0

A solução mais fácil é alterar o nome da tabela e todos os nomes das colunas para minúsculas e seu problema será resolvido.

Por exemplo:

  • Mude Table_Namepara table_name e
  • Mude ColumnNameparacolumnname
meMadhav
fonte