Подключение Django 4 к Postgresql с использованием файла-пароля: «fe_sendauth: пароль не указан»

Здравствуйте, сообщество SO и Django,

Моя проблема связана с Django 4, так как в этой версии появилась возможность использовать файл-пароль для подключения к Postgres. Несмотря на то, что я ответил на аналогичные вопросы, связанные с сообщением об ошибке, о предыдущих версиях, мне не удалось решить мою проблему.

Что я пытаюсь сделать

Я хочу подключить базу данных Postgres DB_MyProject к django MyProject. В Django 4 вы можете использовать файл-пароль вместо предоставления всей информации о пользователе/пароле в файле settings.py. Документация об этой новой функции находится . Концепция файла паролей в Postgres объясняется , вы также можете прочитать о службе подключения .

Следуя этим документам, насколько я понимаю, я сделал следующее:

  1. Создал следующую запись DATABASES в settings.py проекта Django, как указано :
          'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'OPTIONS': {
            'service': 'db_service',
            'passfile': '.pgpass',
        },
    }
} 
  1. В каталоге конфигурации pg () создан файл pg_service.conf со следующей информацией, как в здесьдокументах pg и здесьdjango docsздесь :
      [db_service]
host=localhost
port=5432
dbname=DB_MyProject
user=my_postgres_user
  1. Создал файл .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
  1. Я также создал БД в PGAdmin с указанным именем и убедился, что у пользователя есть разрешение с указанным паролем.

  2. Теперь я предположил, что он должен работать нормально. Но вместо этого, когда я пытаюсь выполнить миграцию, миграцию или запуск сервера, я получаю следующее:

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 ответа

  1. Создал следующую запись DATABASES в settings.pyпроекта Джанго:
          'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'OPTIONS': {
            'service': 'db_service',
            'passfile': '.pgpass',
        },
    }
} 
  1. В домашнем каталоге пользователя создан файл ~/.pg_service.confсо следующей информацией:
      [db_service]
host=localhost
port=5432
dbname=DB_MyProject
user=my_postgres_user
  1. Создал файл .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",
    },
}

}

Другие вопросы по тегам