2017-04-12 36 views
0

問題:使用PSQL pg_dumppg_restore在Python腳本,並使用subprocess模塊。的pg_dump和使用Python模塊子pg_restore的密碼

背景:我使用以下python 2.7腳本從本地主機(即Ubuntu 14.04.5 LTS),以在PSQL服務器上創建一個表的備份(即PostgreSQL 9.4.11),並將其恢復到遠程主機(即Ubuntu 16.04.2 LTS)在更新版本的PSQL服務器(即PostgreSQL 9.6.2)。

#!/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.

回答

1

以下工作並取得被註釋掉的變化。

我不知道但爲什麼pg_restore使用了全命令(即未在列表中拆分),並在Popen使用shell=True時產生密碼驗證錯誤,但pg_dump,另一方面工作正常使用shell=True &完整的命令。 <必須做任何事情嗎?

#!/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()