2015-02-09 25 views
1

或多或少的這個功能是我們爲我們的服務檯技術人員使用的實用程序的一部分,旨在爲他們提供從postgres備份中提取表的簡單方法,重命名錶並重新插入它進入另一個數據庫。使用cur.execute()函數將表格真正插入到所選數據庫中之前,我的函數運行良好。 sed(是的,我想堅持sed)和提取部分很好。我想用psycopg2以某種方式執行該文件,但如果有人有使用子進程和psql的想法,我可以接受其他建議。 使用表名稱列表,目標數據庫和sql文件備份調用此函數。我見過使用.read()的其他例子。我也知道我應該把文件名變成一個變量來清理代碼。如果可能的話,它還需要使用python 2.6。在psycopg2中執行sql文件

for tbl in selected_tables: 
    # Open a file each iteration, dump the table in to it. Use .wait() to make sure the command finishes. 
    table_file = open(str(tbl) + backup_suffix + ".sql", "w") 
    p1 = subprocess.Popen(["/usr/bin/pg_restore", backup_picked, "-t", tbl], stdout=table_file) 
    p1.wait() 

    # Rename every instance of the table in the restore file. Format: _backup_YYYYMMDD 
    sed_guts = "s/" + str(tbl) + "/" + str(tbl) + backup_suffix + "/g" 
    p2 = subprocess.Popen(["/bin/sed", "-i", sed_guts, str(tbl) + backup_suffix + ".sql"]) 
    p2.wait() 
    table_file.close() 

    # Restore the tables. 
    try: 
     # Gets the proper connection information. Works fine. 
     site_config = site.ParseConfig(target_site) 

     contents = open(str(tbl) + backup_suffix + ".sql", "r") 


     con = psycopg2.connect(user=site_config['dbusername'],host=site_config['host'], \ 
          password= site_config['password'], port=site_config['port'],\ 
          dbname=site_config['dbname']) 

     con.set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT) 

     # Connect to postgres or to the db and then execute the query. 
     cur = con.cursor() 
     # Fails here 
     cur.execute(contents.read()) 
     os.remove(str(tbl) + backup_suffix + ".sql") 

    except: 
     os.remove(str(tbl) + backup_suffix + ".sql") 
+0

你不應該關閉p1.wait(後table_file文件,並運行前在它上面? – 2015-02-10 01:08:42

+0

好的想法,我改變了我的代碼以反映你的建議,但它似乎沒有影響。 – 2015-02-10 16:56:29

回答

0

最後我最終回到了psql和subprocess.Popen的shell = True。這不是我喜歡的方法,因爲我有其他限制,我願意走這條路。如果有人在這裏好奇,我做了什麼。

backup_suffix = site.FileSuffix(backup_picked) 

# Do the actual restoration here. Use sed to rename every instance in the files that will be created below. 
# Make sure the created files get removed before finishing. 
for tbl in selected_tables: 
    table_file_name = str(tbl) + backup_suffix + ".sql" 

    # Open a file each iteration, dump the table in to it. Use .wait() to make sure the command finishes. 
    table_file = open(table_file_name, "w") 
    p1 = subprocess.Popen(["/usr/bin/pg_restore", backup_picked, "-t", tbl], stdout=table_file) 
    p1.wait() 
    table_file.close() 

    # Rename every instance of the table in the restore file. Format: _backup_YYYYMMDD 
    sed_guts = "s/" + str(tbl) + "/" + str(tbl) + backup_suffix + "/g" 
    p2 = subprocess.Popen(["/bin/sed", "-i", sed_guts, table_file_name]) 
    p2.wait() 

    # Use psql to restore the tables. 
    try: 
     site_config = site.ParseConfig(target_site) 
     dontuse, site_config = addFlags(site_config, site_config) 

     command = '/usr/bin/psql %s %s %s %s < %s' % (site_config['host'], site_config['dbusername'], 
                 site_config['dbname'], site_config['port'], table_file_name) 

     p2 = subprocess.Popen('%s' % command, shell=True) 
     p2.communicate()[0] 

     os.remove(table_file_name) 

    except: 
     os.remove(table_file_name) 
     session.CleanUp() 

    exit(0) 

還有多種方法可以將多個變量寫入字符串中。如果有人想了解這裏有一個鏈接,以幫助: Using multiple arguments for string formatting in Python (e.g., '%s ... %s')

下面是開在Python另一個很好的資源關閉文件:) http://www.tutorialspoint.com/python/python_files_io.htm

相關問題