Mercurial > kallithea
comparison rhodecode/lib/dbmigrate/migrate/versioning/schemadiff.py @ 1203:6832ef664673 beta
source code cleanup: remove trailing white space, normalize file endings
author | Marcin Kuzminski <marcin@python-works.com> |
---|---|
date | Sun, 03 Apr 2011 18:23:15 +0200 |
parents | 08d2dcd71666 |
children | 5b2cf21b1947 |
comparison
equal
deleted
inserted
replaced
1202:eef9e273347a | 1203:6832ef664673 |
---|---|
37 class ColDiff(object): | 37 class ColDiff(object): |
38 """ | 38 """ |
39 Container for differences in one :class:`~sqlalchemy.schema.Column` | 39 Container for differences in one :class:`~sqlalchemy.schema.Column` |
40 between two :class:`~sqlalchemy.schema.Table` instances, ``A`` | 40 between two :class:`~sqlalchemy.schema.Table` instances, ``A`` |
41 and ``B``. | 41 and ``B``. |
42 | 42 |
43 .. attribute:: col_A | 43 .. attribute:: col_A |
44 | 44 |
45 The :class:`~sqlalchemy.schema.Column` object for A. | 45 The :class:`~sqlalchemy.schema.Column` object for A. |
46 | 46 |
47 .. attribute:: col_B | 47 .. attribute:: col_B |
48 | 48 |
49 The :class:`~sqlalchemy.schema.Column` object for B. | 49 The :class:`~sqlalchemy.schema.Column` object for B. |
50 | 50 |
51 .. attribute:: type_A | 51 .. attribute:: type_A |
52 | 52 |
53 The most generic type of the :class:`~sqlalchemy.schema.Column` | 53 The most generic type of the :class:`~sqlalchemy.schema.Column` |
54 object in A. | 54 object in A. |
55 | 55 |
56 .. attribute:: type_B | 56 .. attribute:: type_B |
57 | 57 |
58 The most generic type of the :class:`~sqlalchemy.schema.Column` | 58 The most generic type of the :class:`~sqlalchemy.schema.Column` |
59 object in A. | 59 object in A. |
60 | 60 |
61 """ | 61 """ |
62 | 62 |
63 diff = False | 63 diff = False |
64 | 64 |
65 def __init__(self,col_A,col_B): | 65 def __init__(self,col_A,col_B): |
66 self.col_A = col_A | 66 self.col_A = col_A |
67 self.col_B = col_B | 67 self.col_B = col_B |
85 A = getattr(self.type_A,attr,None) | 85 A = getattr(self.type_A,attr,None) |
86 B = getattr(self.type_B,attr,None) | 86 B = getattr(self.type_B,attr,None) |
87 if not (A is None or B is None) and A!=B: | 87 if not (A is None or B is None) and A!=B: |
88 self.diff=True | 88 self.diff=True |
89 return | 89 return |
90 | 90 |
91 def __nonzero__(self): | 91 def __nonzero__(self): |
92 return self.diff | 92 return self.diff |
93 | 93 |
94 class TableDiff(object): | 94 class TableDiff(object): |
95 """ | 95 """ |
96 Container for differences in one :class:`~sqlalchemy.schema.Table` | 96 Container for differences in one :class:`~sqlalchemy.schema.Table` |
97 between two :class:`~sqlalchemy.schema.MetaData` instances, ``A`` | 97 between two :class:`~sqlalchemy.schema.MetaData` instances, ``A`` |
98 and ``B``. | 98 and ``B``. |
99 | 99 |
100 .. attribute:: columns_missing_from_A | 100 .. attribute:: columns_missing_from_A |
101 | 101 |
102 A sequence of column names that were found in B but weren't in | 102 A sequence of column names that were found in B but weren't in |
103 A. | 103 A. |
104 | 104 |
105 .. attribute:: columns_missing_from_B | 105 .. attribute:: columns_missing_from_B |
106 | 106 |
107 A sequence of column names that were found in A but weren't in | 107 A sequence of column names that were found in A but weren't in |
108 B. | 108 B. |
109 | 109 |
110 .. attribute:: columns_different | 110 .. attribute:: columns_different |
111 | 111 |
112 A dictionary containing information about columns that were | 112 A dictionary containing information about columns that were |
113 found to be different. | 113 found to be different. |
114 It maps column names to a :class:`ColDiff` objects describing the | 114 It maps column names to a :class:`ColDiff` objects describing the |
124 return bool( | 124 return bool( |
125 self.columns_missing_from_A or | 125 self.columns_missing_from_A or |
126 self.columns_missing_from_B or | 126 self.columns_missing_from_B or |
127 self.columns_different | 127 self.columns_different |
128 ) | 128 ) |
129 | 129 |
130 class SchemaDiff(object): | 130 class SchemaDiff(object): |
131 """ | 131 """ |
132 Compute the difference between two :class:`~sqlalchemy.schema.MetaData` | 132 Compute the difference between two :class:`~sqlalchemy.schema.MetaData` |
133 objects. | 133 objects. |
134 | 134 |
137 :class:`~sqlalchemy.schema.MetaData` objects. | 137 :class:`~sqlalchemy.schema.MetaData` objects. |
138 | 138 |
139 The length of a :class:`SchemaDiff` will give the number of | 139 The length of a :class:`SchemaDiff` will give the number of |
140 changes found, enabling it to be used much like a boolean in | 140 changes found, enabling it to be used much like a boolean in |
141 expressions. | 141 expressions. |
142 | 142 |
143 :param metadataA: | 143 :param metadataA: |
144 First :class:`~sqlalchemy.schema.MetaData` to compare. | 144 First :class:`~sqlalchemy.schema.MetaData` to compare. |
145 | 145 |
146 :param metadataB: | 146 :param metadataB: |
147 Second :class:`~sqlalchemy.schema.MetaData` to compare. | 147 Second :class:`~sqlalchemy.schema.MetaData` to compare. |
148 | 148 |
149 :param labelA: | 149 :param labelA: |
150 The label to use in messages about the first | 150 The label to use in messages about the first |
151 :class:`~sqlalchemy.schema.MetaData`. | 151 :class:`~sqlalchemy.schema.MetaData`. |
152 | 152 |
153 :param labelB: | 153 :param labelB: |
154 The label to use in messages about the second | 154 The label to use in messages about the second |
155 :class:`~sqlalchemy.schema.MetaData`. | 155 :class:`~sqlalchemy.schema.MetaData`. |
156 | 156 |
157 :param excludeTables: | 157 :param excludeTables: |
158 A sequence of table names to exclude. | 158 A sequence of table names to exclude. |
159 | 159 |
160 .. attribute:: tables_missing_from_A | 160 .. attribute:: tables_missing_from_A |
161 | 161 |
162 A sequence of table names that were found in B but weren't in | 162 A sequence of table names that were found in B but weren't in |
163 A. | 163 A. |
164 | 164 |
165 .. attribute:: tables_missing_from_B | 165 .. attribute:: tables_missing_from_B |
166 | 166 |
167 A sequence of table names that were found in A but weren't in | 167 A sequence of table names that were found in A but weren't in |
168 B. | 168 B. |
169 | 169 |
170 .. attribute:: tables_different | 170 .. attribute:: tables_different |
171 | 171 |
172 A dictionary containing information about tables that were found | 172 A dictionary containing information about tables that were found |
173 to be different. | 173 to be different. |
174 It maps table names to a :class:`TableDiff` objects describing the | 174 It maps table names to a :class:`TableDiff` objects describing the |
193 B_table_names - A_table_names - excludeTables | 193 B_table_names - A_table_names - excludeTables |
194 ) | 194 ) |
195 self.tables_missing_from_B = sorted( | 195 self.tables_missing_from_B = sorted( |
196 A_table_names - B_table_names - excludeTables | 196 A_table_names - B_table_names - excludeTables |
197 ) | 197 ) |
198 | 198 |
199 self.tables_different = {} | 199 self.tables_different = {} |
200 for table_name in A_table_names.intersection(B_table_names): | 200 for table_name in A_table_names.intersection(B_table_names): |
201 | 201 |
202 td = TableDiff() | 202 td = TableDiff() |
203 | 203 |
204 A_table = metadataA.tables[table_name] | 204 A_table = metadataA.tables[table_name] |
205 B_table = metadataB.tables[table_name] | 205 B_table = metadataB.tables[table_name] |
206 | 206 |
207 A_column_names = set(A_table.columns.keys()) | 207 A_column_names = set(A_table.columns.keys()) |
208 B_column_names = set(B_table.columns.keys()) | 208 B_column_names = set(B_table.columns.keys()) |
209 | 209 |
210 td.columns_missing_from_A = sorted( | 210 td.columns_missing_from_A = sorted( |
211 B_column_names - A_column_names | 211 B_column_names - A_column_names |
212 ) | 212 ) |
213 | 213 |
214 td.columns_missing_from_B = sorted( | 214 td.columns_missing_from_B = sorted( |
215 A_column_names - B_column_names | 215 A_column_names - B_column_names |
216 ) | 216 ) |
217 | 217 |
218 td.columns_different = {} | 218 td.columns_different = {} |
219 | 219 |
220 for col_name in A_column_names.intersection(B_column_names): | 220 for col_name in A_column_names.intersection(B_column_names): |
221 | 221 |
222 cd = ColDiff( | 222 cd = ColDiff( |
224 B_table.columns.get(col_name) | 224 B_table.columns.get(col_name) |
225 ) | 225 ) |
226 | 226 |
227 if cd: | 227 if cd: |
228 td.columns_different[col_name]=cd | 228 td.columns_different[col_name]=cd |
229 | 229 |
230 # XXX - index and constraint differences should | 230 # XXX - index and constraint differences should |
231 # be checked for here | 231 # be checked for here |
232 | 232 |
233 if td: | 233 if td: |
234 self.tables_different[table_name]=td | 234 self.tables_different[table_name]=td |
235 | 235 |
236 def __str__(self): | 236 def __str__(self): |
237 ''' Summarize differences. ''' | 237 ''' Summarize differences. ''' |
238 out = [] | 238 out = [] |
239 column_template =' %%%is: %%r' % self.label_width | 239 column_template =' %%%is: %%r' % self.label_width |
240 | 240 |
241 for names,label in ( | 241 for names,label in ( |
242 (self.tables_missing_from_A,self.labelA), | 242 (self.tables_missing_from_A,self.labelA), |
243 (self.tables_missing_from_B,self.labelB), | 243 (self.tables_missing_from_B,self.labelB), |
244 ): | 244 ): |
245 if names: | 245 if names: |
246 out.append( | 246 out.append( |
247 ' tables missing from %s: %s' % ( | 247 ' tables missing from %s: %s' % ( |
248 label,', '.join(sorted(names)) | 248 label,', '.join(sorted(names)) |
249 ) | 249 ) |
250 ) | 250 ) |
251 | 251 |
252 for name,td in sorted(self.tables_different.items()): | 252 for name,td in sorted(self.tables_different.items()): |
253 out.append( | 253 out.append( |
254 ' table with differences: %s' % name | 254 ' table with differences: %s' % name |
255 ) | 255 ) |
256 for names,label in ( | 256 for names,label in ( |
265 ) | 265 ) |
266 for name,cd in td.columns_different.items(): | 266 for name,cd in td.columns_different.items(): |
267 out.append(' column with differences: %s' % name) | 267 out.append(' column with differences: %s' % name) |
268 out.append(column_template % (self.labelA,cd.col_A)) | 268 out.append(column_template % (self.labelA,cd.col_A)) |
269 out.append(column_template % (self.labelB,cd.col_B)) | 269 out.append(column_template % (self.labelB,cd.col_B)) |
270 | 270 |
271 if out: | 271 if out: |
272 out.insert(0, 'Schema diffs:') | 272 out.insert(0, 'Schema diffs:') |
273 return '\n'.join(out) | 273 return '\n'.join(out) |
274 else: | 274 else: |
275 return 'No schema diffs' | 275 return 'No schema diffs' |