26 from collections import OrderedDict |
26 from collections import OrderedDict |
27 |
27 |
28 from pgtoolkit import pgbrowser |
28 from pgtoolkit import pgbrowser |
29 from pycolib.ansicolor import * |
29 from pycolib.ansicolor import * |
30 |
30 |
|
31 import sys |
|
32 |
31 |
33 |
32 class DiffData: |
34 class DiffData: |
33 COLORS = { |
35 COLORS = { |
34 '+' : BOLD | GREEN, |
36 '+' : BOLD | GREEN, |
35 '-' : BOLD | RED, |
37 '-' : BOLD | RED, |
36 '*' : BOLD | YELLOW, |
38 '*' : BOLD | YELLOW, |
37 'V' : BOLD | WHITE, |
39 'V' : BOLD | WHITE, |
38 'K' : BOLD | BLUE} |
40 'K' : BOLD | BLUE} |
39 |
41 |
40 def __init__(self, change, cols1, cols2, key=None): |
42 def __init__(self, change, cols1, cols2, key=None): |
41 ''' |
43 """ |
42 |
44 |
43 change - one of '+', '-', '*' (add, remove, update) |
45 change - one of '+', '-', '*' (add, remove, update) |
44 cols1 - original column values (OrderedDict) |
46 cols1 - original column values (OrderedDict) |
45 cols2 - new column values (OrderedDict) |
47 cols2 - new column values (OrderedDict) |
46 key - primary key columns (OrderedDict) |
48 key - primary key columns (OrderedDict) |
47 |
49 |
48 ''' |
50 """ |
49 self.change = change |
51 self.change = change |
50 self.cols1 = cols1 |
52 self.cols1 = cols1 |
51 self.cols2 = cols2 |
53 self.cols2 = cols2 |
52 self.key = key |
54 self.key = key |
53 |
55 |
153 self.schema2 = schema |
155 self.schema2 = schema |
154 self.table2 = table |
156 self.table2 = table |
155 self.fulltable2 = '"' + schema + '"."'+ table + '"' |
157 self.fulltable2 = '"' + schema + '"."'+ table + '"' |
156 |
158 |
157 def iter_diff(self): |
159 def iter_diff(self): |
158 '''Return differencies between data of two tables. |
160 """Return differencies between data of two tables. |
159 |
161 |
160 Yields one line at the time. |
162 Yields one line at the time. |
161 |
163 |
162 ''' |
164 """ |
163 curs1, curs2 = self._select() |
165 curs1, curs2 = self._select() |
164 |
166 |
165 row1 = curs1.fetchone_dict() |
167 row1 = curs1.fetchone_dict() |
166 row2 = curs2.fetchone_dict() |
168 row2 = curs2.fetchone_dict() |
167 |
169 |
184 row2 = curs2.fetchone_dict() |
186 row2 = curs2.fetchone_dict() |
185 |
187 |
186 curs1.close() |
188 curs1.close() |
187 curs2.close() |
189 curs2.close() |
188 |
190 |
189 def print_diff(self): |
191 def print_diff(self, file=sys.stdout): |
190 '''Print differencies between data of two tables. |
192 """Print differencies between data of two tables. |
191 |
193 |
192 The output is in human readable form. |
194 The output is in human readable form. |
193 |
195 |
194 Set allowcolor=True of PgDataDiff instance to get colored output. |
196 Set allowcolor=True of PgDataDiff instance to get colored output. |
195 |
197 |
196 ''' |
198 """ |
197 for ln in self.iter_diff(): |
199 for ln in self.iter_diff(): |
198 print(ln.format()) |
200 print(ln.format(), file=file) |
199 |
201 |
200 def print_patch(self): |
202 def print_patch(self, file=sys.stdout): |
201 '''Print SQL script usable as patch for destination table. |
203 """Print SQL script usable as patch for destination table. |
202 |
204 |
203 Supports INSERT, DELETE and UPDATE operations. |
205 Supports INSERT, DELETE and UPDATE operations. |
204 |
206 |
205 ''' |
207 """ |
206 for ln in self.iter_diff(): |
208 for ln in self.iter_diff(): |
207 print(ln.format_patch(self.fulltable1)) |
209 print(ln.format_patch(self.fulltable1), file=file) |
208 |
210 |
209 def _select(self): |
211 def _select(self): |
210 browser = pgbrowser.PgBrowser(self.conn1) |
212 browser = pgbrowser.PgBrowser(self.conn1) |
211 |
213 |
212 columns = browser.list_columns(schema=self.schema1, table=self.table1, order=1) |
214 columns = browser.list_columns(schema=self.schema1, table=self.table1, order=1) |