Skip to content

Commit e6bf388

Browse files
author
Dave Charness
committed
Add comparison of SQLAlchemy Enums
Compare enum types and/or check constraints where supported by the database.
1 parent 278a406 commit e6bf388

File tree

2 files changed

+69
-2
lines changed

2 files changed

+69
-2
lines changed

sqlalchemydiff/comparer.py

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,12 @@ def compare(left_uri, right_uri, ignores=None, ignores_sep=None):
9393
tables_info.common, left_inspector, right_inspector, ignore_manager
9494
)
9595

96+
info['enums'] = _get_enums_info(
97+
left_inspector,
98+
right_inspector,
99+
ignore_manager.get('*', 'enum'),
100+
)
101+
96102
errors = _compile_errors(info)
97103
result = _make_result(info, errors)
98104

@@ -161,6 +167,7 @@ def _get_info_dict(left_uri, right_uri, tables_info):
161167
'common': tables_info.common,
162168
},
163169
'tables_data': {},
170+
'enums': {},
164171
}
165172

166173
return info
@@ -214,6 +221,13 @@ def _get_table_data(
214221
ignore_manager.get(table_name, 'col')
215222
)
216223

224+
table_data['constraints'] = _get_constraints_info(
225+
left_inspector,
226+
right_inspector,
227+
table_name,
228+
ignore_manager.get(table_name, 'cons')
229+
)
230+
217231
return table_data
218232

219233

@@ -335,6 +349,53 @@ def _get_columns(inspector, table_name):
335349
return inspector.get_columns(table_name)
336350

337351

352+
def _get_constraints_info(left_inspector, right_inspector,
353+
table_name, ignores):
354+
left_constraints_list = _get_constraints_data(left_inspector, table_name)
355+
right_constraints_list = _get_constraints_data(right_inspector, table_name)
356+
357+
left_constraints_list = _discard_ignores_by_name(left_constraints_list,
358+
ignores)
359+
right_constraints_list = _discard_ignores_by_name(right_constraints_list,
360+
ignores)
361+
362+
# process into dict
363+
left_constraints = dict((elem['name'], elem)
364+
for elem in left_constraints_list)
365+
right_constraints = dict((elem['name'], elem)
366+
for elem in right_constraints_list)
367+
368+
return _diff_dicts(left_constraints, right_constraints)
369+
370+
371+
def _get_constraints_data(inspector, table_name):
372+
try:
373+
return inspector.get_check_constraints(table_name)
374+
except NotImplementedError:
375+
return []
376+
377+
378+
def _get_enums_info(left_inspector, right_inspector, ignores):
379+
left_enums_list = _get_enums_data(left_inspector)
380+
right_enums_list = _get_enums_data(right_inspector)
381+
382+
left_enums_list = _discard_ignores_by_name(left_enums_list, ignores)
383+
right_enums_list = _discard_ignores_by_name(right_enums_list, ignores)
384+
385+
# process into dict
386+
left_enums = dict((elem['name'], elem) for elem in left_enums_list)
387+
right_enums = dict((elem['name'], elem) for elem in right_enums_list)
388+
389+
return _diff_dicts(left_enums, right_enums)
390+
391+
392+
def _get_enums_data(inspector):
393+
try:
394+
return inspector.get_enums()
395+
except AttributeError:
396+
return []
397+
398+
338399
def _discard_ignores_by_name(items, ignores):
339400
return [item for item in items if item['name'] not in ignores]
340401

@@ -364,6 +425,7 @@ def _compile_errors(info):
364425
errors_template = {
365426
'tables': {},
366427
'tables_data': {},
428+
'enums': {},
367429
}
368430
errors = deepcopy(errors_template)
369431

@@ -375,7 +437,8 @@ def _compile_errors(info):
375437
errors['tables']['right_only'] = info['tables']['right_only']
376438

377439
# then check if there is a discrepancy in the data for each table
378-
keys = ['foreign_keys', 'primary_keys', 'indexes', 'columns']
440+
keys = ['foreign_keys', 'primary_keys', 'indexes', 'columns',
441+
'constraints']
379442
subkeys = ['left_only', 'right_only', 'diff']
380443

381444
for table_name in info['tables_data']:
@@ -386,6 +449,10 @@ def _compile_errors(info):
386449
table_d.setdefault(key, {})[subkey] = info[
387450
'tables_data'][table_name][key][subkey]
388451

452+
for subkey in subkeys:
453+
if info['enums'][subkey]:
454+
errors['enums'][subkey] = info['enums'][subkey]
455+
389456
if errors != errors_template:
390457
errors['uris'] = info['uris']
391458
return errors

sqlalchemydiff/util.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ def prepare_schema_from_models(uri, sqlalchemy_base):
108108

109109
class IgnoreManager:
110110

111-
allowed_identifiers = ['pk', 'fk', 'idx', 'col']
111+
allowed_identifiers = ['pk', 'fk', 'idx', 'col', 'cons', 'enum']
112112

113113
def __init__(self, ignores, separator=None):
114114
self.separator = separator or '.'

0 commit comments

Comments
 (0)