Подключение Django 4 к Postgresql с использованием файла-пароля: «fe_sendauth: пароль не указан»
Здравствуйте, сообщество SO и Django,
Моя проблема связана с Django 4, так как в этой версии появилась возможность использовать файл-пароль для подключения к Postgres. Несмотря на то, что я ответил на аналогичные вопросы, связанные с сообщением об ошибке, о предыдущих версиях, мне не удалось решить мою проблему.
Что я пытаюсь сделать
Я хочу подключить базу данных Postgres DB_MyProject к django MyProject. В Django 4 вы можете использовать файл-пароль вместо предоставления всей информации о пользователе/пароле в файле settings.py. Документация об этой новой функции находится . Концепция файла паролей в Postgres объясняется , вы также можете прочитать о службе подключения .
Следуя этим документам, насколько я понимаю, я сделал следующее:
- Создал следующую запись DATABASES в settings.py проекта Django, как указано :
'default': {
'ENGINE': 'django.db.backends.postgresql',
'OPTIONS': {
'service': 'db_service',
'passfile': '.pgpass',
},
}
}
- В каталоге конфигурации pg () создан файл pg_service.conf со следующей информацией, как в здесьдокументах pg и здесьdjango docsздесь :
[db_service]
host=localhost
port=5432
dbname=DB_MyProject
user=my_postgres_user
- Создал файл .pgpass, как в здесьpg docs :
localhost:5432:DB_MyProject:my_postgres_user:my_passwd
Теперь этот файл .pgpass существует в нескольких местах в результате стремления заставить это работать:
- в каталоге конфигурации pg (
pg_config --sysconfdir
) - в моем домашнем каталоге обычного пользователя ~/
- в корневом каталоге django MyProject
все эти файлы являются точными копиями с одинаковым уровнем разрешений:
-rw------- 1 my_regular_user my_group 52 Mar 2 18:47 .pgpass
Я также создал БД в PGAdmin с указанным именем и убедился, что у пользователя есть разрешение с указанным паролем.
Теперь я предположил, что он должен работать нормально. Но вместо этого, когда я пытаюсь выполнить миграцию, миграцию или запуск сервера, я получаю следующее:
django.db.utils.OperationalError: подключение к серверу по адресу «localhost» (::1), ошибка порта 5432: fe_sendauth: пароль не указан
Что я уже пробовал
- проверенная совместимость: Django v4.0.3, PostgreSQL v14.0, psycopg2 v2.9.3
- создал переменную среды PGPASSFILE с путем к ~./.pgpass
- изменил владельца ~/.pgpass с my_regular_user на my_postgres_user для тестирования, получил тот же результат
- установил direnv, создал файл .envrc в корневом каталоге проекта, содержащий:
export PGPASSFILE=~/.pgpass
Спасибо заранее за вашу помощь. Я также был бы рад, если бы мне указали на любые неправильные представления в моем мышлении, поскольку я начинающий разработчик.
4 ответа
- Создал следующую запись DATABASES в
settings.py
проекта Джанго:
'default': {
'ENGINE': 'django.db.backends.postgresql',
'OPTIONS': {
'service': 'db_service',
'passfile': '.pgpass',
},
}
}
- В домашнем каталоге пользователя создан файл
~/.pg_service.conf
со следующей информацией:
[db_service]
host=localhost
port=5432
dbname=DB_MyProject
user=my_postgres_user
- Создал файл .pgpass в корневом каталоге django MyProject и изменил права доступа к файлу.
chmod 0600 MyProject/.pgpass
:
localhost:5432:DB_MyProject:my_postgres_user:my_passwd
У меня недостаточно репутации, чтобы комментировать, поэтому, чтобы добавить к ответу gtlee, я тоже мог заставить файл паролей работать только в том случае, если он находился в домашнем каталоге проекта django.
Похоже, что хотя установка переменной среды PGSERVICEFILE позволяет вам разместить служебный файл в любом месте вашей системы Linux, переменная среды PGPASSFILE просто игнорируется. Немного раздражает, поскольку он добавляет еще один файл для добавления в .gitignore.
Альтернативное решение — использовать служебный файл, а затем передать пароль как обычно, но сохранить его в переменной среды.
Единственная проблема, которую я вижу в ответе @gtlee, заключается в том, что вы храните свой файл доступа внутри своего проекта. Обычно это не очень хорошая практика, если вы планируете отправить свой код в репозиторий кода. Вы хотите хранить файлы учетных данных вне своей кодовой базы. Вот что я сделал:
settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': os.environ.get('DATABASE_NAME'),
'USER': os.environ.get('DATABASE_USER'),
'PASSWORD': os.environ.get('DATABASE_PASSWORD'),
'HOST': 'localhost',
'PORT': '5432',
}
}
Убедитесь, что вы импортировали модуль os в файл settings.py:
import os
Затем на моем сервере Ubuntu, где размещен мой сервер PostgreSQL, я установил эти переменные среды в моем файле ~/.bashrc в самом конце файла:
export DATABASE_NAME=mydatabase
export DATABASE_USER=myuser
export DATABASE_PASSWORD=mypassword
Затем просто запустите следующую команду, чтобы сбросить изменения:
source ~/.bashrc
Затем, как только вы снова запустите python3 Manage.py runserver, он должен работать.
Приятного кодирования! :)
Я обнаружил, что если вы сделаете это так, как настроен postgresql, он будет работать без необходимости упоминать файл паролей в настройках.
Документация Django Документация
Postgres
Создайтеpgpass.conf
файл (там же, где находится.pg_service.conf
файл), затем удалите'passfile': '.my_pgpass'
вход вOPTIONS
Это приведет к тому, что Django проигнорирует местонахождение файла паролей, а Postgresql выполнит процесс по умолчанию.
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
"OPTIONS": {
"service": "my_service",
},
}
}