tablecopy.py
changeset 56 94e091c23ebb
parent 35 e7f79c4a27ce
child 93 b72591087495
equal deleted inserted replaced
55:adc1615d8fc5 56:94e091c23ebb
     1 #!/usr/bin/env python3.2
     1 #!/usr/bin/env python3.2
     2 #
     2 #
     3 # Copy data between tables with same table schema.
     3 # Copy data between tables with same table schema.
     4 #
     4 #
       
     5 # Copies full table, target table must be empty.
     5 # Can copy multiple tables in one run.
     6 # Can copy multiple tables in one run.
     6 # Sorts the tables according to references.
     7 # Sorts the tables according to references.
     7 #
     8 #
     8 # This may be used instead of dump/restore.
     9 # This may be used instead of dump/restore.
     9 #
    10 #
    15 
    16 
    16 
    17 
    17 class TableCopyTool(toolbase.SrcDstTablesTool):
    18 class TableCopyTool(toolbase.SrcDstTablesTool):
    18     def __init__(self):
    19     def __init__(self):
    19         toolbase.SrcDstTablesTool.__init__(self, name='tablecopy', desc='Table copy tool.')
    20         toolbase.SrcDstTablesTool.__init__(self, name='tablecopy', desc='Table copy tool.')
    20         
    21 
    21         self.parser.add_argument('-n', '--no-action', dest='noaction', action='store_true',
    22         self.parser.add_argument('-n', '--no-action', dest='noaction', action='store_true',
    22             help="Do nothing, just print tables to be copied. Useful in combination with --regex.")
    23             help="Do nothing, just print tables to be copied. Useful in combination with --regex.")
    23         self.parser.add_argument('--no-sort', dest='nosort', action='store_true',
    24         self.parser.add_argument('--no-sort', dest='nosort', action='store_true',
    24             help="Do not sort. By default, tables are sorted by foreign key references.")
    25             help="Do not sort. By default, tables are sorted by foreign key references.")
    25         
    26 
    26         self.init()
    27         self.init()
    27 
    28 
    28     def main(self):
    29     def main(self):
    29         self.srcconn = self.pgm.get_conn('src')
    30         self.srcconn = self.pgm.get_conn('src')
    30         self.dstconn = self.pgm.get_conn('dst')
    31         self.dstconn = self.pgm.get_conn('dst')
    31         
    32 
    32         dc = pgdatacopy.PgDataCopy(self.srcconn, self.dstconn)
    33         dc = pgdatacopy.PgDataCopy(self.srcconn, self.dstconn)
    33         
    34 
    34         if self.args.nosort:
    35         if self.args.nosort:
    35             for table in self.tables():
    36             for table in self.tables():
    36                 self.copy_table(dc, *table)
    37                 self.copy_table(dc, *table)
    37         else:
    38         else:
    38             # sort tables with respect to references
    39             # sort tables with respect to references
    39             details = dict()
    40             details = dict()
    40             pending = set()
    41             pending = set()
    41             references = dict()
    42             references = dict()
    42             
    43 
    43             # build list of all table to be copied (pending) and references map
    44             # build list of all table to be copied (pending) and references map
    44             for table in self.tables():
    45             for table in self.tables():
    45                 srcschema, srctable, dstschema, dsttable = table
    46                 srcschema, srctable, dstschema, dsttable = table
    46                 name = dstschema + '.' + dsttable
    47                 name = dstschema + '.' + dsttable
    47                 details[name] = table
    48                 details[name] = table
    48                 pending.add(name)
    49                 pending.add(name)
    49                 references[name] = self.get_references(dstschema, dsttable)
    50                 references[name] = self.get_references(dstschema, dsttable)
    50             
    51 
    51             # copy files with fulfilled references, repeat until all done
    52             # copy files with fulfilled references, repeat until all done
    52             while pending:
    53             while pending:
    53                 for name in list(pending):
    54                 for name in list(pending):
    54                     ok = True
    55                     ok = True
    55                     for ref in references[name]:
    56                     for ref in references[name]:
    67 
    68 
    68     def copy_table(self, dc, srcschema, srctable, dstschema, dsttable):
    69     def copy_table(self, dc, srcschema, srctable, dstschema, dsttable):
    69         print('Copying [%s] %s.%s --> [%s] %s.%s' % (
    70         print('Copying [%s] %s.%s --> [%s] %s.%s' % (
    70             self.args.src, srcschema, srctable,
    71             self.args.src, srcschema, srctable,
    71             self.args.dst, dstschema, dsttable))
    72             self.args.dst, dstschema, dsttable))
    72         
    73 
    73         if self.args.noaction:
    74         if self.args.noaction:
    74             return
    75             return
    75         
    76 
    76         dc.set_source(srctable, srcschema)
    77         dc.set_source(srctable, srcschema)
    77         dc.set_destination(dsttable, dstschema)
    78         dc.set_destination(dsttable, dstschema)
    78         
    79 
    79         try:
    80         try:
    80             dc.check()
    81             dc.check()
    81         except pgdatacopy.TargetNotEmptyError as e:
    82         except pgdatacopy.TargetNotEmptyError as e:
    82             print(' - error:', str(e))
    83             print(' - error:', str(e))
    83             return
    84             return
    84         
    85 
    85         print(' - read                           ')
    86         print(' - read                           ')
    86         buf = io.BytesIO()
    87         buf = io.BytesIO()
    87         wrapped = ProgressWrapper(buf)
    88         wrapped = ProgressWrapper(buf)
    88         dc.read(wrapped)
    89         dc.read(wrapped)
    89         data = buf.getvalue()
    90         data = buf.getvalue()
    90         buf.close()
    91         buf.close()
    91         
    92 
    92         print(' - write                          ')
    93         print(' - write                          ')
    93         buf = io.BytesIO(data)
    94         buf = io.BytesIO(data)
    94         wrapped = ProgressWrapper(buf, len(data))
    95         wrapped = ProgressWrapper(buf, len(data))
    95         dc.write(wrapped)
    96         dc.write(wrapped)
    96         buf.close()
    97         buf.close()
    97         
    98 
    98         print(' - analyze                        ')
    99         print(' - analyze                        ')
    99         dc.analyze()
   100         dc.analyze()
   100 
   101 
   101 
   102 
   102 tool = TableCopyTool()
   103 tool = TableCopyTool()