2015-02-09 27 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

相关问题