Как указать пароль для pg_dump без запроса?

У меня есть следующий код Python, который работает локально для создания дампа. Я хотел бы докеризовать его без подсказки пароля для подключения к базе данных, когда я использую команду pg_dump, а также я не знаю, что я дам в файле докеры вместо postgres_bin = r"C:\Program Files\PostgreSQL\13\ мусорное ведро

import os
import paramiko
import subprocess

postgres_bin = r"C:\Program Files\PostgreSQL\13\bin"
dump_file = "database_dump.sql"

with open(dump_file, "w") as f:
    result = subprocess.call([os.path.join(postgres_bin, "pg_dump"), "-Fp", "-d", "XXX", "-U", "XXX", "-h", "XXX", "-p", "XXX"], stdout=f)

transport.close()

Этот код работает локально. Я хотел бы, чтобы тот же код работал без необходимости указывать пароль в приглашении, которое у меня есть локально.

Как мне это сделать ?

---- ОБНОВЛЯТЬ ----

Я обновил свой код ниже. Этот код работает с подсказкой. Но когда я раскомментирую строку с помощью «-w» и env = {'PGPASSWORD': 'secret'}, у меня возникает ошибка, что имя хоста не может быть переведено: неизвестная ошибка сервера.

import os
import paramiko
import subprocess

print("Import has been done !")

postgres_bin = r"C:\Program Files\PostgreSQL\13\bin"
dump_file = "database_dump.sql"

with open(dump_file, "w") as f:
        result = subprocess.call([
                os.path.join(postgres_bin, "pg_dump"), 
                "-Fp", 
                "-d", 
                "anonymedev", 
                "-U", 
                "pgsqladmin", 
                "-h", 
                "hostname", 
                "-p", 
                "32045", 
                # '-w'
                ], 
                # env = {'PGPASSWORD': 'secret'},
                stdout=f
                )

Вы можете использовать переменные среды PGPASSWORD или PGPASSFILE, как описано в документации.

larsks 03.02.2023 21:07

Я попробовал это, но не работал. Я думаю, что вы правы, и я не использовал его хорошо. У вас есть пример, пожалуйста?

lbened 03.02.2023 21:12
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
2
65
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете использовать переменные среды PGPASSWORD или PGPASSFILE, как описано в документации.

Например, чтобы вывести базу данных «пример» от имени пользователя «postgres» с паролем «secret», я могу написать:

PGHOST=127.0.0.1 \
PGUSER=postgres \
PGPASSWORD=secret \
PGDATABASE=example \
pg_dump

Я могу сохранить пароль в файле вместо использования переменной окружения PGPASSWORD; в этом случае нам нужно отформатировать файл, как описано в «Файл паролей»:

echo 127.0.0.1:5432:example:postgres:secret

А затем сослаться на этот файл с помощью переменной окружения PGPASSFILE:

PGPASSFILE=pgpass \
pg_dump -h 127.0.0.1 -U postgres example

Если вы запускаете pg_dump из Python, то для установки переменной среды вам нужно установить ключи в os.environ или использовать параметр env для subprocess.call.

Использование параметра env устанавливает среду для этого единственного вызова subprocess.call, и вы должны явно включить существующие переменные среды, если хотите, чтобы они были видны в дочернем процессе:

with open(dump_file, "w") as f:
    result = subprocess.call(
        [
            os.path.join(postgres_bin, "pg_dump"),
            "-Fp",
            "-d",
            "XXX",
            "-U",
            "XXX",
            "-h",
            "XXX",
            "-p",
            "XXX",
        ],
        env=os.environ | {'PGPASSWORD': 'secret'},
        stdout=f,
    )

(Обратите внимание, что синтаксис dict union здесь требует Python 3.9 или более поздней версии).

В качестве альтернативы вы можете обновить os.environ, что сделает переменную доступной для всех последующих подпроцессов:

os.environ['PGPASSWORD'] = 'secret'

with open(dump_file, "w") as f:
    result = subprocess.call(
        [
            os.path.join(postgres_bin, "pg_dump"),
            "-Fp",
            "-d",
            "XXX",
            "-U",
            "XXX",
            "-h",
            "XXX",
            "-p",
            "XXX",
        ],
        stdout=f,
    )

Перед "с открытым..." в моем коде я добавил PGPASSWORD=secret, но соединение не работает.

lbened 03.02.2023 21:41

Смотрите обновление к моему ответу.

larsks 03.02.2023 22:20

Спасибо, я добавил это: env = {'PGPASSWORD': 'secret'}, но теперь у меня ошибка, что имя хоста не может быть переведено: неизвестная ошибка сервера. Это работает, когда я не добавляю env = {'PGPASSWORD': 'secret'}. Так что не знаю, откуда проблема.

lbened 04.02.2023 08:42

Хост является удаленным хостом PGAAS

lbened 04.02.2023 09:21

Это может быть ошибка в вашем коде, но чтобы диагностировать ее, мне нужно увидеть фактический код с вашими последними изменениями. Может быть, вы могли бы обновить свой вопрос и добавить его?

larsks 04.02.2023 13:25

Я обновил свой вопрос кодом, который использовал с вашим ответом

lbened 04.02.2023 13:37

Извините, это была моя ошибка! Установка env на subprocess.call переопределяет среду процесса, поэтому вы должны явно включать существующие переменные среды. Я обновил ответ здесь двумя альтернативами.

larsks 04.02.2023 13:45

Спасибо ! Я пробовал две возможности. Сначала выдается ошибка: TypeError: неподдерживаемые типы операндов для |: '_Environ' и 'dict'. Второй вариант работает! Есть ли у вас какие-либо советы о том, как я могу защитить его больше о пароле? Моя конечная цель — поместить этот код в приложение flask и докеризовать его. Может быть, жестко закодированный пароль не подходит

lbened 04.02.2023 13:53

Конечно, жестко закодированный пароль — плохая идея. Распространенным решением является чтение пароля из среды — таким образом, его можно прочитать из .env, предоставленного приложению, или в docker, или docker-compose, или через docker run -e PGPASSWORD = "...", и т. д.

larsks 04.02.2023 14:06

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