-
Notifications
You must be signed in to change notification settings - Fork 19
Compare Enum types #11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
1f1212c
7c5505c
8c59af8
0f8e69c
b16a525
411c8f8
b67fa24
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -93,6 +93,12 @@ def compare(left_uri, right_uri, ignores=None, ignores_sep=None): | |
tables_info.common, left_inspector, right_inspector, ignore_manager | ||
) | ||
|
||
info['enums'] = _get_enums_info( | ||
left_inspector, | ||
right_inspector, | ||
ignore_manager.get('*', 'enum'), | ||
) | ||
|
||
errors = _compile_errors(info) | ||
result = _make_result(info, errors) | ||
|
||
|
@@ -161,6 +167,7 @@ def _get_info_dict(left_uri, right_uri, tables_info): | |
'common': tables_info.common, | ||
}, | ||
'tables_data': {}, | ||
'enums': {}, | ||
} | ||
|
||
return info | ||
|
@@ -214,6 +221,13 @@ def _get_table_data( | |
ignore_manager.get(table_name, 'col') | ||
) | ||
|
||
table_data['constraints'] = _get_constraints_info( | ||
left_inspector, | ||
right_inspector, | ||
table_name, | ||
ignore_manager.get(table_name, 'cons') | ||
) | ||
|
||
return table_data | ||
|
||
|
||
|
@@ -335,6 +349,53 @@ def _get_columns(inspector, table_name): | |
return inspector.get_columns(table_name) | ||
|
||
|
||
def _get_constraints_info(left_inspector, right_inspector, | ||
table_name, ignores): | ||
left_constraints_list = _get_constraints_data(left_inspector, table_name) | ||
right_constraints_list = _get_constraints_data(right_inspector, table_name) | ||
|
||
left_constraints_list = _discard_ignores_by_name(left_constraints_list, | ||
ignores) | ||
right_constraints_list = _discard_ignores_by_name(right_constraints_list, | ||
ignores) | ||
|
||
# process into dict | ||
left_constraints = dict((elem['name'], elem) | ||
for elem in left_constraints_list) | ||
right_constraints = dict((elem['name'], elem) | ||
for elem in right_constraints_list) | ||
|
||
return _diff_dicts(left_constraints, right_constraints) | ||
|
||
|
||
def _get_constraints_data(inspector, table_name): | ||
try: | ||
return inspector.get_check_constraints(table_name) | ||
except NotImplementedError: | ||
return [] | ||
|
||
|
||
def _get_enums_info(left_inspector, right_inspector, ignores): | ||
left_enums_list = _get_enums_data(left_inspector) | ||
right_enums_list = _get_enums_data(right_inspector) | ||
|
||
left_enums_list = _discard_ignores_by_name(left_enums_list, ignores) | ||
right_enums_list = _discard_ignores_by_name(right_enums_list, ignores) | ||
|
||
# process into dict | ||
left_enums = dict((elem['name'], elem) for elem in left_enums_list) | ||
right_enums = dict((elem['name'], elem) for elem in right_enums_list) | ||
|
||
return _diff_dicts(left_enums, right_enums) | ||
|
||
|
||
def _get_enums_data(inspector): | ||
try: | ||
return inspector.get_enums() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. perhaps we could add a comment here mentioning that this is specific to the postgres inspector? |
||
except AttributeError: | ||
return [] | ||
|
||
|
||
def _discard_ignores_by_name(items, ignores): | ||
return [item for item in items if item['name'] not in ignores] | ||
|
||
|
@@ -364,6 +425,7 @@ def _compile_errors(info): | |
errors_template = { | ||
'tables': {}, | ||
'tables_data': {}, | ||
'enums': {}, | ||
} | ||
errors = deepcopy(errors_template) | ||
|
||
|
@@ -375,7 +437,8 @@ def _compile_errors(info): | |
errors['tables']['right_only'] = info['tables']['right_only'] | ||
|
||
# then check if there is a discrepancy in the data for each table | ||
keys = ['foreign_keys', 'primary_keys', 'indexes', 'columns'] | ||
keys = ['foreign_keys', 'primary_keys', 'indexes', 'columns', | ||
'constraints'] | ||
subkeys = ['left_only', 'right_only', 'diff'] | ||
|
||
for table_name in info['tables_data']: | ||
|
@@ -386,6 +449,10 @@ def _compile_errors(info): | |
table_d.setdefault(key, {})[subkey] = info[ | ||
'tables_data'][table_name][key][subkey] | ||
|
||
for subkey in subkeys: | ||
if info['enums'][subkey]: | ||
errors['enums'][subkey] = info['enums'][subkey] | ||
|
||
if errors != errors_template: | ||
errors['uris'] = info['uris'] | ||
return errors | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -108,6 +108,39 @@ def test_errors_dict_catches_all_differences(uri_left, uri_right): | |
} | ||
}, | ||
'employees': { | ||
'columns': { | ||
'diff': [ | ||
{ | ||
'key': 'polarity', | ||
'left': { | ||
'default': None, | ||
'name': 'polarity', | ||
'nullable': True, | ||
'type': "ENUM('NEGATIVE','POSITIVE')"}, | ||
'right': { | ||
'default': None, | ||
'name': 'polarity', | ||
'nullable': True, | ||
'type': "ENUM('NEG','POS')" | ||
} | ||
}, | ||
{ | ||
'key': 'spin', | ||
'left': { | ||
'default': None, | ||
'name': 'spin', | ||
'nullable': True, | ||
'type': 'VARCHAR(9)' | ||
}, | ||
'right': { | ||
'default': None, | ||
'name': 'spin', | ||
'nullable': True, | ||
'type': 'VARCHAR(4)' | ||
} | ||
} | ||
] | ||
}, | ||
'foreign_keys': { | ||
'left_only': [ | ||
{ | ||
|
@@ -215,6 +248,8 @@ def test_errors_dict_catches_all_differences(uri_left, uri_right): | |
} | ||
} | ||
}, | ||
'enums': { | ||
}, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm seeing an error when running this test:
It looks like we are now getting an extra There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (TIL) Comment support is new in SQLAlchemy 1.2.0: http://docs.sqlalchemy.org/en/latest/changelog/migration_12.html#change-1546 The change adds a I think the most straightforward way to go here is to key off that attribute (e.g., Perhaps, though, That selectivity should also help make the tests work for a dialect other than mysql (e.g., postgresql), though left_only and right_only would still fail without further work. Your thoughts? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agree it would be better to be more selective in the assertions rather than comparing the whole result. But if that's too big a change, your first suggestion will do the job well enough for now. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For now, I've implemented the simpler change. I didn't want the more-directed tests to hold up this PR. |
||
'uris': { | ||
'left': uri_left, | ||
'right': uri_right, | ||
|
@@ -299,6 +334,8 @@ def test_ignores(uri_left, uri_right): | |
'phone_numbers', | ||
'companies.col.name', | ||
'companies.idx.name', | ||
'employees.col.polarity', | ||
'employees.col.spin', | ||
'employees.fk.fk_employees_companies', | ||
'employees.fk.fk_emp_comp', | ||
'employees.idx.ix_employees_name', | ||
|
@@ -330,6 +367,8 @@ def test_ignores_alternative_sep(uri_left, uri_right): | |
'phone_numbers', | ||
'companies#col#name', | ||
'companies#idx#name', | ||
'employees#col#polarity', | ||
'employees#col#spin', | ||
'employees#fk#fk_employees_companies', | ||
'employees#fk#fk_emp_comp', | ||
'employees#idx#ix_employees_name', | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is new in sqlalchemy 1.1.0 - could you add the
sqlalchemy>=1.1.0
requirement to setup.py?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe, instead, catch
AttributeError
alongsideNotImplementedError
and return the same empty list? (A comment mentioning 1.1.0, similar to the one you request below forget_enums
, would make sense.)I think better to leave the sqlalchemy version unconstrained if doing so requires so little.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah yes - good idea! - let's do the error catching instead.