【问题标题】:Executing a sql file in psycopg2在 psycopg2 中执行 sql 文件
【发布时间】:2015-02-09 21:02:32
【问题描述】:

此功能或多或少是我们用于帮助台技术人员的实用程序的一部分,旨在为他们提供一种从 postgres 备份中提取表、重命名表并将其重新插入另一个数据库的简单方法。在使用 cur.execute() 将表实际插入所选数据库之前,我的函数运行良好。 sed(是的,我想坚持使用 sed)和提取部分效果很好。我想用 psycopg2 以某种方式执行该文件,但如果有人有使用 subprocess 和 psql 的想法,我愿意接受其他建议。 使用表名列表、目标数据库和 sql 文件备份调用此函数。我见过使用 .read() 的其他示例。我也知道我应该把文件名变成一个变量来清理一下代码。如果可能,它还需要使用 python 2.6。

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")

【问题讨论】:

  • 你不应该在 p1.wait() 之后和运行 sed 之前关闭 table_file 文件吗?
  • 好主意,我更改了代码以反映您的建议,但似乎失败并没有影响。

标签: python python-2.7 psycopg2


【解决方案1】:

最后,我最终回到了 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

【讨论】:

    猜你喜欢
    • 2013-06-20
    • 1970-01-01
    • 2016-07-24
    • 2018-02-11
    • 2011-05-12
    • 2016-11-18
    • 1970-01-01
    • 2016-12-26
    • 1970-01-01
    相关资源
    最近更新 更多