pg_dump&pg_restore password使用python模块子进程

2024-06-06 22:02:24 发布

您现在位置:Python中文网/ 问答频道 /正文

问题:在Python脚本中使用PSQLpg_dumppg_restore,并使用subprocess模块。

背景:我正在使用本地主机(即Ubuntu 14.04.5 LTS)中的以下python 2.7脚本在PSQL服务器(即PostgreSQL 9.4.11)中创建表的备份,并将其还原到较新版本PSQL服务器(即PostgreSQL 9.6.2)中的远程主机(即Ubuntu 16.04.2 LTS)。

#!/usr/bin/python

from subprocess import PIPE,Popen

def dump_table(host_name,database_name,user_name,database_password,table_name):

    command = 'pg_dump -h {0} -d {1} -U {2} -p 5432 -t public.{3} -Fc -f /tmp/table.dmp'\
    .format(host_name,database_name,user_name,table_name)

    p = Popen(command,shell=True,stdin=PIPE)

    return p.communicate('{}\n'.format(database_password))

def restore_table(host_name,database_name,user_name,database_password):

    command = 'pg_restore -h {0} -d {1} -U {2} < /tmp/table.dmp'\
    .format(host_name,database_name,user_name)

    p = Popen(command,shell=True,stdin=PIPE)

    return p.communicate('{}\n'.format(database_password))

def main():
    dump_table('localhost','testdb','user_name','passwd','test_tbl')
    restore_table('remotehost','new_db','user_name','passwd')

if __name__ == "__main__":
    main()

当我按上述顺序使用函数时,dump_table()函数成功完成并创建/tmp/table.sql文件,但restore_table()函数返回以下错误:

('', 'Password: \npg_restore: [archiver (db)] connection to database "database_name" failed: FATAL: password authentication failed for user "username"\nFATAL: password authentication failed for user "username"\n')*

我通过执行shell中的pg_restore命令检查了凭据和输出,还包括了.pgpass的凭据(尽管由于我在p.communicate()中传递了密码,因此与此无关)

有没有类似的经历?我被卡住了!

谨致问候, D


Tags: nameformathostdeftablerestorepassworddump
2条回答

对以下工作和所做的更改进行了评论。

我不知道为什么pg_restore在使用full命令(即不在列表中拆分)和在Popen中使用shell=True时会产生密码验证错误,但是pg_dump在另一方面使用shell=True&;full命令可以正常工作。<与此有关吗?

#!/usr/bin/python

from subprocess import PIPE,Popen
import shlex

def dump_table(host_name,database_name,user_name,database_password,table_name):

    command = 'pg_dump -h {0} -d {1} -U {2} -p 5432 -t public.{3} -Fc -f /tmp/table.dmp'\
    .format(host_name,database_name,user_name,table_name)

    p = Popen(command,shell=True,stdin=PIPE,stdout=PIPE,stderr=PIPE)

    return p.communicate('{}\n'.format(database_password))

def restore_table(host_name,database_name,user_name,database_password):

    #Remove the '<' from the pg_restore command.
    command = 'pg_restore -h {0} -d {1} -U {2} /tmp/table.dmp'\
              .format(host_name,database_name,user_name)

    #Use shlex to use a list of parameters in Popen instead of using the
    #command as is.
    command = shlex.split(command)

    #Let the shell out of this (i.e. shell=False)
    p = Popen(command,shell=False,stdin=PIPE,stdout=PIPE,stderr=PIPE)

    return p.communicate('{}\n'.format(database_password))

def main():
    dump_table('localhost','testdb','user_name','passwd','test_tbl')
    restore_table('localhost','testdb','user_name','passwd')

if __name__ == "__main__":
    main()

您可以将环境变量https://www.postgresql.org/docs/11/libpq-envars.html和“--no password”选项用于pg_dump。

    def dump_schema(host, dbname, user, password, **kwargs):
        command = f'pg_dump --host={host} ' \
            f'--dbname={dbname} ' \
            f'--username={user} ' \
            f'--no-password ' \
            f'--format=c ' \
            f'--file=/tmp/schema.dmp '

        proc = Popen(command, shell=True, env={
            'PGPASSWORD': password
        })
        proc.wait()

相关问题 更多 >