django.db.utils.OperationalError: FATAL: 角色 "django" 不存在。

15
我按照Digital Ocean的这篇教程在Ubuntu 16.04服务器上安装了PostgreSQL 9.5,以便与Django 1.10一起使用。操作进展顺利,但我无法让Django应用程序连接数据库(或者看起来是这样)。应用程序和数据库都在同一台服务器上。
以下是一些设置、配置和报告: 我收到的错误信息:
File "/home/mathieu/web/agencies/lib/python3.5/site-packages/psycopg2/__init__.py", line 164, in connect
conn = _connect(dsn, connection_factory=connection_factory, async=async)
django.db.utils.OperationalError: FATAL:  role "django" does not exist

我的 Django 项目的数据库设置:
DATABASES = {
'sqlite3': {
    'ENGINE': 'django.db.backends.sqlite3',
    'NAME': os.path.join(BASE_DIR, 'db.sqlite3')
},
'default': {
    'ENGINE': 'django.db.backends.postgresql',
    'NAME': 'agencies',
    'USER': 'django',
    'PASSWORD': '<password>',
    'HOST': 'localhost',
    'PORT': '5432',
}}

hba_file

postgres=# SHOW hba_file;
hba_file
--------------------------------------
/etc/postgresql/9.5/main/pg_hba.conf

它的内容(至少是相关部分):

Its contents

# TYPE  DATABASE        USER            ADDRESS                 METHOD

# "local" is for Unix domain socket connections only
local   all             all                                     peer
# IPv4 local connections:
host    all             all             127.0.0.1/32            md5
# IPv6 local connections:
host    all             all             ::1/128                 md5
# Allow replication connections from localhost, by a user with the
# replication privilege.
#local   replication     postgres                                peer
#host    replication     postgres        127.0.0.1/32            md5
#host    replication     postgres        ::1/128                 md5

在 psql 中的用户和数据库

postgres=# \du
                               List of roles
Role name |                         Attributes                         | Member of
-----------+------------------------------------------------------------+-----------
django    |                                                            | {}
postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS | {}


postgres=# \l
                              List of databases
Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges
-----------+----------+----------+-------------+-------------+-----------------------
agencies  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =Tc/postgres         +
                                                            |  postgres=CTc/postgres+
                                                            |  django=CTc/postgres
postgres  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
template0 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
          |          |          |             |             |  postgres=CTc/postgres
template1 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
          |          |          |             |             | postgres=CTc/postgres

我在虚拟机上(运行Linux Mint,我应该说)按照完全相同的步骤进行了操作,一切都很顺利...

我无论如何都想不出问题出在哪里。


非常奇怪,因为它应该给出消息“用户"django"的密码验证失败”,它永远不会向未经过身份验证的人透露用户是否存在。这一定是我们没有看到的非常明显的事情。你能显示完整的回溯吗? - Antonis Christofides
此外,在您的 settings.py 中,尝试将用户 "django" 更改为 "django1" 和 "postgres"(使用错误的密码); 在这些情况下它会给出什么错误信息? - Antonis Christofides
几乎可以确定它正在连接到与您想要的不同的PostgreSQL。尝试指定不同的“HOST”,例如不存在的主机,以及“127.0.0.1”,看看会发生什么。 - Antonis Christofides
2
经过我们的调查,我们发现在一个被遗忘的Docker容器中存在第二个PostgreSQL实例。不确定这对其他用户是否有帮助,因此也许应该将这个问题删除。 - Antonis Christofides
或者它也可以被关闭为离题,其细分类别是:“这个问题由于无法再现或简单的排版错误导致。虽然类似的问题可能是适合讨论的,但这个问题已经以一种不太可能帮助未来读者的方式解决了。” - Antonis Christofides
显示剩余4条评论
4个回答

15

如果您在本地安装了postgres并运行,并且docker容器也在尝试占用相同的端口,您可能会看到此错误。

如果本地实例首先启动并占用了docker镜像也要使用的端口,docker不一定会告诉您这一点。

当您尝试运行django或其他需要数据库的./manage.py命令时,将会看到相同的错误,因为应用程序将无法看到您正在寻找的数据库。

在这种情况下,您可以通过停止服务器,单击服务器设置并更改端口来更改本地安装的postgres端口。您必须更新任何依赖于旧端口的应用程序中的settings.py

据我的经验,在执行此操作后,如果重新启动docker数据库容器,则不会再出现此错误。


你说得对 :) 请参考我在这个问题的另一个答案中的评论 - Mathieu Dhondt
啊,太棒了。我没有看到那个。如果您愿意,请标记问题为已回答/正确! :) - Rob
这正是我的问题,我四处寻找原因,看为什么我的数据库没有被创建 :-P 非常感谢你。 - Mic

6
请参考链接这里,其中有详细的解释。
您的设置为:

'USER': 'django',

但是错误提示该用户不存在,这意味着您尚未创建该用户。
请进入psql的交互会话,并输入以下命令。
CREATE DATABASE agencies;
CREATE USER django WITH PASSWORD 'password';
ALTER ROLE django SET client_encoding TO 'utf8'; 
ALTER ROLE django SET default_transaction_isolation TO 'read committed'; 
ALTER ROLE django SET timezone TO 'Asia/Kolkata';

GRANT ALL PRIVILEGES ON DATABASE agencies TO django;
\q

然后在 settings.py 文件中

'PASSWORD': 'password',

密码不应该用 < > 括起来。


1
谢谢,但原因是一个在Docker容器中运行的第二个PostgreSQL数据库。请参考https://dev59.com/MlgR5IYBdhLWcg3wvPiM#odTonYgBc1ULPQZFNA8z - Mathieu Dhondt

1
如果你正在使用Docker,并且它监听了5432端口,那么你应该杀掉其他也在监听此端口的进程。
为此,请输入以下命令以查看哪些进程正在使用5432端口:
$ lsof -i:5432

This will look like this:

COMMAND     PID           USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
com.docke 15178 andre.carvalho   86u  IPv6 0xb128ac87cd34cc69      0t0  TCP *:postgresql (LISTEN)
postgres  16670 andre.carvalho    7u  IPv6 0xb128ac87dc50c569      0t0  TCP localhost:postgresql (LISTEN)
postgres  16670 andre.carvalho    8u  IPv4 0xb128ac87d2378541      0t0  TCP localhost:postgresql (LISTEN)

接下来很简单:只需使用以下命令杀死另一个进程即可:

kill -9 16670

(请注意,该进程由PID标识。)

0

我认为您忘记给用户“django”添加权限了:

GRANT ALL PRIVILEGES ON DATABASE agencies TO django;

我按照我参考的教程添加了这些权限,但确实在\du概述中似乎没有显示出来。它应该显示吗? - Mathieu Dhondt
PostgreSQL 不会说谎。当它说“不存在”时,就是“不存在”。 - Antonis Christofides
但是当我使用\du命令时,为什么会出现django角色呢? - Mathieu Dhondt
哎呀。我100%确定我已经授予权限,但为了确保我重新执行了一遍。现在访问权限已经有了数据库agencies的条目。我会更新我的问题(因为我收到的错误仍然是相同的)。 - Mathieu Dhondt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接