【问题标题】:Postgresql Database Backup Using Python使用 Python 进行 Postgresql 数据库备份
【发布时间】:2014-05-19 08:20:15
【问题描述】:

我想使用 Python 代码备份数据库。我想备份一些相关数据的表。如何使用“SELECT”语句进行备份以及如何选择所需的表?

例如

我想获取一些表从 2014-05-01 到 2014-05-10 的数据并将这个结果输出为 .sql 扩展文件

如何使用 python 代码获得这种格式? 如果你不介意,请解释一下。 谢谢。

【问题讨论】:

    标签: python postgresql


    【解决方案1】:

    使用 psycopg2 建立数据连接。文档中有很多例子:

    http://initd.org/psycopg/

    配置好数据源后,通过将结果集打印到文件来迭代“SELECT”语句的结果,构建“INSERT INTO”语句。基本上是一些逆向逻辑。

    这样,如果时间到了,您需要使用备份文件,您只需运行 SQL 文件,将数据重新插入...

    例子:

            import psycopg2
            import sys
    
    
            con = None
    
            try:
    
                con = psycopg2.connect(database='local', user='local', password='local',port='1970')
                cur = con.cursor()
                cur.execute('SELECT x FROM t')
                f = open('test.sql', 'w')
                for row in cur:
                  f.write("insert into t values (" + str(row) + ");")
            except psycopg2.DatabaseError, e:
                print 'Error %s' % e
                sys.exit(1)
            finally:
                if con:
                    con.close()
    

    然后恢复:

    psql <dbname> <username> < test.sql
    

    干杯,

    【讨论】:

    • 写入“插入”语句的建议是为了将该代码写入文本文件,而不是从 PsycoPG 调用。一开始的回答让我有点困惑。你应该做类似stackoverflow.com/a/2771803/582906
    • 我想你不明白。使用 SELECT 从表中获取数据后,您可以对这些数据执行任何操作。我要说的是,您可以将 SELECT 反转为 INSERT,这很简单。此外,如果您再次阅读该问题,他希望备份数据的逻辑子集,而不是物理数据。您可以使用 pg_dump -t 等来完成此操作,然后使用他要求的数据子集创建一个备份表。
    • 当然,我理解并且我的回答从一开始就提供了使用自定义查询而不是 pg_dump 的想法。我只是说你的答案的第一个版本可能会导致一些混乱(也许和我一样),现在我相信由于一些代码,两者都得到了改进。
    【解决方案2】:

    如果您的操作系统是 Linux,您可以使用下面的代码。 首先,你应该运行apt-get install postgresql

    
    def create_essentials():
        yaml_file = open("settings.yaml", 'r')
        settings = yaml.load(yaml_file)
        db_name = settings["db_name"]
        db_user = settings["db_user"]
        db_password = settings["db_password"]
        db_host = settings["db_host"]
        db_port = settings["db_port"]
        backup_path = settings["backup_path"]
        filename = settings["filename"]
        filename = filename + "-" + time.strftime("%Y%m%d") + ".backup"
        command_str = str(db_host)+" -p "+str(db_port)+" -d "+db_name+" -U "+db_user
        return command_str, backup_path, filename
    
    
    def backup_database(table_names=None):
        command_str,backup_path,filename = create_essentials()
        command_str = "pg_dump -h "+command_str
    
        if table_names is not None:
            for x in table_names:
                command_str = command_str +" -t "+x
    
        command_str = command_str + " -F c -b -v -f '"+backup_path+"/"+filename+"'"
        try:
            os.system(command_str)
            print "Backup completed"
        except Exception as e:
            print "!!Problem occured!!"
            print e
    
    def restore_database(table_names=None):
        command_str,backup_path,filename = create_essentials()
        command_str = "pg_restore -h "+command_str
    
        if table_names is not None:
            for x in table_names:
                command_str = command_str +" -t "+x
    
        command_str = command_str + " -v '"+backup_path+"/"+filename+"'"
        
        try:
            os.system(command_str)
            print "Restore completed"
        except Exception as e:
            print "!!Problem occured!!"
            print e
    

    【讨论】:

      【解决方案3】:

      我想到的第一个想法是转储你的表调用pg_dump 命令,类似于here 提出的方法(但谷歌有很多选择)。

      但是,由于您的备份策略要求您选择精确的日期而不仅仅是表格,您可能不得不依赖一系列查询,然后我的建议是使用像 Psycopg 这样的库。

      编辑

      由于我不知道,所以无法提供完整的示例:

      • 您要转储哪些表
      • 每个表的精确备份策略是什么(即 SELECT 语句)
      • 您希望如何恢复它们。通过删除表然后重新创建它,通过基于 ID 属性覆盖数据库行,...

      以下示例生成一个存储单个查询结果的文件。

      import psycopg
      
      conn = psycopg2.connect("dbname=test user=postgres")  # change this according to your RDBMS configuration
      cursor = conn.cursor()
      
      table_name='YOUR_TABLE_HERE'  # place your table name here
      with open("table_dump.sql") as f:
          cursor.execute("SELECT * FROM %s" % (table_name))  # change the query according to your needs
          column_names = []
          columns_descr = cursor.description
          for c in columns_descr:
              column_names.append(c[0])
          insert_prefix = 'INSERT INTO %s (%s) VALUES ' % (table_name, ', '.join(column_names))
          rows = cursor.fetchall()
          for row in rows:
          row_data = []
              for rd in row:
                  if rd is None:
                      row_data.append('NULL')
                  elif isinstance(rd, datetime.datetime):
                      row_data.append("'%s'" % (rd.strftime('%Y-%m-%d %H:%M:%S') ))
                  else:
                      row_data.append(repr(rd))
          f.write('%s (%s);\n' % (insert_prefix, ', '.join(row_data)))  # this is the text that will be put in the SQL file. You can change it if you wish.
      

      【讨论】:

      • 如何使用 Psycopg 库获得我的结果。如果我使用这个库,我会得到示例 'SELECT' 查询结果......但我真的想要 .sql 文件,就像 phpmyadmin 的导出文件一样......稍后......我将重用这个 .sql 文件通过导入文件进行恢复。这就是为什么......我不知道如何用python语言编写这段代码......如果你不介意,请为此提供一些示例代码。谢谢。
      • @sharipha,我可以使用 psycopg2 转储数据库吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-17
      • 2015-06-29
      • 2019-09-19
      • 1970-01-01
      • 2014-09-03
      • 2011-09-28
      相关资源
      最近更新 更多