Added support to ignore the owner while comparing objects in the Schema Diff tool. Fixes #5200.

This commit is contained in:
Akshay Joshi 2020-09-28 15:22:46 +05:30
parent 68588fbb44
commit 952197f130
8 changed files with 41 additions and 44 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 KiB

After

Width:  |  Height:  |  Size: 135 KiB

View File

@ -416,6 +416,8 @@ Expand the *Schema Diff* node to specify your display preferences.
:alt: Preferences schema diff :alt: Preferences schema diff
:align: center :align: center
Use the *Ignore owner* switch to ignores the owner while comparing the objects.
Use the *Ignore whitespaces* switch to ignores the whitespaces while comparing Use the *Ignore whitespaces* switch to ignores the whitespaces while comparing
the string objects. Whitespace includes space, tabs, and CRLF. the string objects. Whitespace includes space, tabs, and CRLF.

View File

@ -9,6 +9,7 @@ This release contains a number of bug fixes and new features since the release o
New features New features
************ ************
| `Issue #5200 <https://redmine.postgresql.org/issues/5200>`_ - Added support to ignore the owner while comparing objects in the Schema Diff tool
Housekeeping Housekeeping
************ ************

View File

@ -33,8 +33,12 @@ upper-right hand corner of the tab bar.
:alt: schema diff dialog :alt: schema diff dialog
:align: center :align: center
Use the :ref:`Preferences <preferences>` dialog to specify if *Schema Diff* Use the :ref:`Preferences <preferences>` dialog to specify following:
should open in a new browser tab. Set *Open in new browser tab* option to true.
* *Schema Diff* should open in a new browser tab. Set *Open in new browser tab* option to true.
* *Schema Diff* should ignore the whitespaces while comparing string objects. Set *Ignore whitespaces* option to true.
* *Schema Diff* should ignore the owner while comparing objects. Set *Ignore owner* option to true.
The *Schema Diff* panel is divided into two panels; an Object Comparison panel The *Schema Diff* panel is divided into two panels; an Object Comparison panel
and a DDL Comparison panel. and a DDL Comparison panel.

View File

@ -32,7 +32,7 @@ class SchemaDiffTableCompare(SchemaDiffObjectCompare):
trigger_keys_to_ignore = ['xmin', 'tgrelid', 'tgfoid', 'tfunction', trigger_keys_to_ignore = ['xmin', 'tgrelid', 'tgfoid', 'tfunction',
'tgqual', 'tgconstraint'] 'tgqual', 'tgconstraint']
index_keys_to_ignore = ['relowner', 'indrelid', 'indclass'] index_keys_to_ignore = ['indrelid', 'indclass']
keys_to_ignore = table_keys_to_ignore + constraint_keys_to_ignore \ keys_to_ignore = table_keys_to_ignore + constraint_keys_to_ignore \
+ trigger_keys_to_ignore + index_keys_to_ignore + trigger_keys_to_ignore + index_keys_to_ignore
@ -53,7 +53,6 @@ class SchemaDiffTableCompare(SchemaDiffObjectCompare):
'scid': kwargs.get('target_scid')} 'scid': kwargs.get('target_scid')}
group_name = kwargs.get('group_name') group_name = kwargs.get('group_name')
ignore_whitespaces = kwargs.get('ignore_whitespaces')
source_schema_name = kwargs.get('source_schema_name', None) source_schema_name = kwargs.get('source_schema_name', None)
source_tables = {} source_tables = {}
target_tables = {} target_tables = {}
@ -77,7 +76,6 @@ class SchemaDiffTableCompare(SchemaDiffObjectCompare):
node=self.node_type, node=self.node_type,
node_label=self.blueprint.collection_label, node_label=self.blueprint.collection_label,
group_name=group_name, group_name=group_name,
ignore_whitespaces=ignore_whitespaces,
ignore_keys=self.keys_to_ignore, ignore_keys=self.keys_to_ignore,
source_schema_name=source_schema_name) source_schema_name=source_schema_name)
@ -246,7 +244,6 @@ class SchemaDiffTableCompare(SchemaDiffObjectCompare):
source = kwargs.get('source') source = kwargs.get('source')
target = kwargs.get('target') target = kwargs.get('target')
diff_dict = kwargs.get('diff_dict') diff_dict = kwargs.get('diff_dict')
ignore_whitespaces = kwargs.get('ignore_whitespaces')
# Get the difference result for source and target columns # Get the difference result for source and target columns
col_diff = self.table_col_comp(source, target) col_diff = self.table_col_comp(source, target)
@ -308,7 +305,6 @@ class SchemaDiffTableCompare(SchemaDiffObjectCompare):
other_param = { other_param = {
"dict1": dict1, "dict1": dict1,
"dict2": dict2, "dict2": dict2,
"ignore_whitespaces": ignore_whitespaces,
"source": source, "source": source,
"target": target "target": target
} }
@ -353,14 +349,12 @@ class SchemaDiffTableCompare(SchemaDiffObjectCompare):
**kwargs): **kwargs):
dict1 = kwargs['dict1'] dict1 = kwargs['dict1']
dict2 = kwargs['dict2'] dict2 = kwargs['dict2']
ignore_whitespaces = kwargs['ignore_whitespaces']
source = kwargs['source'] source = kwargs['source']
target = kwargs['target'] target = kwargs['target']
for key in intersect_keys: for key in intersect_keys:
# Recursively Compare the two dictionary # Recursively Compare the two dictionary
if not are_dictionaries_identical( if not are_dictionaries_identical(
dict1[key], dict2[key], ignore_whitespaces, dict1[key], dict2[key], self.keys_to_ignore):
self.keys_to_ignore):
diff_ddl = module_view.ddl_compare( diff_ddl = module_view.ddl_compare(
source_params=source_params, source_params=source_params,
target_params=target_params, target_params=target_params,

View File

@ -25,7 +25,6 @@ from pgadmin.tools.schema_diff.node_registry import SchemaDiffRegistry
from pgadmin.tools.schema_diff.model import SchemaDiffModel from pgadmin.tools.schema_diff.model import SchemaDiffModel
from config import PG_DEFAULT_DRIVER from config import PG_DEFAULT_DRIVER
from pgadmin.utils.driver import get_driver from pgadmin.utils.driver import get_driver
from pgadmin.utils.preferences import Preferences
from pgadmin.utils.constants import PREF_LABEL_DISPLAY, MIMETYPE_APP_JS,\ from pgadmin.utils.constants import PREF_LABEL_DISPLAY, MIMETYPE_APP_JS,\
ERROR_MSG_TRANS_ID_NOT_FOUND ERROR_MSG_TRANS_ID_NOT_FOUND
from sqlalchemy import or_ from sqlalchemy import or_
@ -93,6 +92,15 @@ class SchemaDiffModule(PgAdminModule):
'tabs, and CRLF') 'tabs, and CRLF')
) )
self.preference.register(
'display', 'ignore_owner',
gettext("Ignore owner"), 'boolean', False,
category_label=PREF_LABEL_DISPLAY,
help_str=gettext('If set to True, then the Schema Diff '
'tool ignores the owner while comparing '
'the objects.')
)
blueprint = SchemaDiffModule(MODULE_NAME, __name__, static_url_path='/static') blueprint = SchemaDiffModule(MODULE_NAME, __name__, static_url_path='/static')
@ -452,9 +460,6 @@ def compare(trans_id, source_sid, source_did, target_sid, target_did):
diff_model_obj) diff_model_obj)
try: try:
pref = Preferences.module('schema_diff')
ignore_whitespaces = pref.preference('ignore_whitespaces').get()
# Fetch all the schemas of source and target database # Fetch all the schemas of source and target database
# Compare them and get the status. # Compare them and get the status.
schema_result = fetch_compare_schemas(source_sid, source_did, schema_result = fetch_compare_schemas(source_sid, source_did,
@ -477,8 +482,7 @@ def compare(trans_id, source_sid, source_did, target_sid, target_did):
source_sid=source_sid, source_did=source_did, source_sid=source_sid, source_did=source_did,
target_sid=target_sid, target_did=target_did, target_sid=target_sid, target_did=target_did,
diff_model_obj=diff_model_obj, total_percent=total_percent, diff_model_obj=diff_model_obj, total_percent=total_percent,
node_percent=node_percent, node_percent=node_percent)
ignore_whitespaces=ignore_whitespaces)
comparison_result = \ comparison_result = \
comparison_result + comparison_schema_result comparison_result + comparison_schema_result
@ -496,7 +500,6 @@ def compare(trans_id, source_sid, source_did, target_sid, target_did):
diff_model_obj=diff_model_obj, diff_model_obj=diff_model_obj,
total_percent=total_percent, total_percent=total_percent,
node_percent=node_percent, node_percent=node_percent,
ignore_whitespaces=ignore_whitespaces,
is_schema_source_only=True) is_schema_source_only=True)
comparison_result = \ comparison_result = \
@ -514,8 +517,7 @@ def compare(trans_id, source_sid, source_did, target_sid, target_did):
schema_name=item['schema_name'], schema_name=item['schema_name'],
diff_model_obj=diff_model_obj, diff_model_obj=diff_model_obj,
total_percent=total_percent, total_percent=total_percent,
node_percent=node_percent, node_percent=node_percent)
ignore_whitespaces=ignore_whitespaces)
comparison_result = \ comparison_result = \
comparison_result + comparison_schema_result comparison_result + comparison_schema_result
@ -533,8 +535,7 @@ def compare(trans_id, source_sid, source_did, target_sid, target_did):
schema_name=item['schema_name'], schema_name=item['schema_name'],
diff_model_obj=diff_model_obj, diff_model_obj=diff_model_obj,
total_percent=total_percent, total_percent=total_percent,
node_percent=node_percent, node_percent=node_percent)
ignore_whitespaces=ignore_whitespaces)
comparison_result = \ comparison_result = \
comparison_result + comparison_schema_result comparison_result + comparison_schema_result
@ -695,7 +696,6 @@ def compare_database_objects(**kwargs):
diff_model_obj = kwargs.get('diff_model_obj') diff_model_obj = kwargs.get('diff_model_obj')
total_percent = kwargs.get('total_percent') total_percent = kwargs.get('total_percent')
node_percent = kwargs.get('node_percent') node_percent = kwargs.get('node_percent')
ignore_whitespaces = kwargs.get('ignore_whitespaces')
comparison_result = [] comparison_result = []
all_registered_nodes = SchemaDiffRegistry.get_registered_nodes(None, all_registered_nodes = SchemaDiffRegistry.get_registered_nodes(None,
@ -715,8 +715,7 @@ def compare_database_objects(**kwargs):
source_did=source_did, source_did=source_did,
target_sid=target_sid, target_sid=target_sid,
target_did=target_did, target_did=target_did,
group_name=gettext('Database Objects'), group_name=gettext('Database Objects'))
ignore_whitespaces=ignore_whitespaces)
if res is not None: if res is not None:
comparison_result = comparison_result + res comparison_result = comparison_result + res
@ -744,7 +743,6 @@ def compare_schema_objects(**kwargs):
diff_model_obj = kwargs.get('diff_model_obj') diff_model_obj = kwargs.get('diff_model_obj')
total_percent = kwargs.get('total_percent') total_percent = kwargs.get('total_percent')
node_percent = kwargs.get('node_percent') node_percent = kwargs.get('node_percent')
ignore_whitespaces = kwargs.get('ignore_whitespaces')
is_schema_source_only = kwargs.get('is_schema_source_only', False) is_schema_source_only = kwargs.get('is_schema_source_only', False)
source_schema_name = None source_schema_name = None
if is_schema_source_only: if is_schema_source_only:
@ -773,7 +771,6 @@ def compare_schema_objects(**kwargs):
target_did=target_did, target_did=target_did,
target_scid=target_scid, target_scid=target_scid,
group_name=gettext(schema_name), group_name=gettext(schema_name),
ignore_whitespaces=ignore_whitespaces,
source_schema_name=source_schema_name) source_schema_name=source_schema_name)
if res is not None: if res is not None:

View File

@ -58,7 +58,6 @@ class SchemaDiffObjectCompare:
'did': kwargs.get('target_did')} 'did': kwargs.get('target_did')}
group_name = kwargs.get('group_name') group_name = kwargs.get('group_name')
ignore_whitespaces = kwargs.get('ignore_whitespaces')
source_schema_name = kwargs.get('source_schema_name', None) source_schema_name = kwargs.get('source_schema_name', None)
source = {} source = {}
target = {} target = {}
@ -89,7 +88,6 @@ class SchemaDiffObjectCompare:
node=self.node_type, node=self.node_type,
node_label=self.blueprint.collection_label, node_label=self.blueprint.collection_label,
group_name=group_name, group_name=group_name,
ignore_whitespaces=ignore_whitespaces,
ignore_keys=self.keys_to_ignore, ignore_keys=self.keys_to_ignore,
source_schema_name=source_schema_name) source_schema_name=source_schema_name)

View File

@ -13,6 +13,7 @@ import copy
import string import string
from pgadmin.tools.schema_diff.model import SchemaDiffModel from pgadmin.tools.schema_diff.model import SchemaDiffModel
from flask import current_app from flask import current_app
from pgadmin.utils.preferences import Preferences
count = 1 count = 1
@ -218,7 +219,6 @@ def _get_identical_and_different_list(intersect_keys, source_dict, target_dict,
different = [] different = []
dict1 = kwargs['dict1'] dict1 = kwargs['dict1']
dict2 = kwargs['dict2'] dict2 = kwargs['dict2']
ignore_whitespaces = kwargs['ignore_whitespaces']
ignore_keys = kwargs['ignore_keys'] ignore_keys = kwargs['ignore_keys']
source_params = kwargs['source_params'] source_params = kwargs['source_params']
target_params = kwargs['target_params'] target_params = kwargs['target_params']
@ -233,8 +233,7 @@ def _get_identical_and_different_list(intersect_keys, source_dict, target_dict,
current_app.logger.debug( current_app.logger.debug(
"Schema Diff: Target Dict: {0}".format(dict2[key])) "Schema Diff: Target Dict: {0}".format(dict2[key]))
if are_dictionaries_identical(dict1[key], dict2[key], if are_dictionaries_identical(dict1[key], dict2[key], ignore_keys):
ignore_whitespaces, ignore_keys):
identical.append({ identical.append({
'id': count, 'id': count,
'type': node, 'type': node,
@ -282,8 +281,7 @@ def _get_identical_and_different_list(intersect_keys, source_dict, target_dict,
diff_ddl = view_object.get_sql_from_submodule_diff( diff_ddl = view_object.get_sql_from_submodule_diff(
source_params=temp_src_params, source_params=temp_src_params,
target_params=temp_tgt_params, target_params=temp_tgt_params,
source=dict1[key], target=dict2[key], diff_dict=diff_dict, source=dict1[key], target=dict2[key], diff_dict=diff_dict)
ignore_whitespaces=ignore_whitespaces)
else: else:
temp_src_params = copy.deepcopy(source_params) temp_src_params = copy.deepcopy(source_params)
temp_tgt_params = copy.deepcopy(target_params) temp_tgt_params = copy.deepcopy(target_params)
@ -343,7 +341,6 @@ def compare_dictionaries(**kwargs):
target_dict = kwargs.get('target_dict') target_dict = kwargs.get('target_dict')
node = kwargs.get('node') node = kwargs.get('node')
node_label = kwargs.get('node_label') node_label = kwargs.get('node_label')
ignore_whitespaces = kwargs.get('ignore_whitespaces')
ignore_keys = kwargs.get('ignore_keys', None) ignore_keys = kwargs.get('ignore_keys', None)
source_schema_name = kwargs.get('source_schema_name') source_schema_name = kwargs.get('source_schema_name')
@ -375,11 +372,20 @@ def compare_dictionaries(**kwargs):
target_only = _get_target_list(removed, target_dict, node, target_params, target_only = _get_target_list(removed, target_dict, node, target_params,
view_object, node_label, group_name) view_object, node_label, group_name)
pref = Preferences.module('schema_diff')
ignore_owner = pref.preference('ignore_owner').get()
# if ignore_owner if True then add all the possible owner keys to the
# ignore keys.
if ignore_owner:
owner_keys = ['owner', 'eventowner', 'funcowner', 'fdwowner',
'fsrvowner', 'lanowner', 'relowner', 'seqowner',
'typowner', 'typeowner']
ignore_keys = ignore_keys + owner_keys
# Compare the values of duplicates keys. # Compare the values of duplicates keys.
other_param = { other_param = {
"dict1": dict1, "dict1": dict1,
"dict2": dict2, "dict2": dict2,
"ignore_whitespaces": ignore_whitespaces,
"ignore_keys": ignore_keys, "ignore_keys": ignore_keys,
"source_params": source_params, "source_params": source_params,
"target_params": target_params, "target_params": target_params,
@ -393,13 +399,11 @@ def compare_dictionaries(**kwargs):
return source_only + target_only + different + identical return source_only + target_only + different + identical
def are_lists_identical(source_list, target_list, ignore_whitespaces, def are_lists_identical(source_list, target_list, ignore_keys):
ignore_keys):
""" """
This function is used to compare two list. This function is used to compare two list.
:param source_list: :param source_list:
:param target_list: :param target_list:
:param ignore_whitespaces: ignore whitespaces
:param ignore_keys: ignore keys to compare :param ignore_keys: ignore keys to compare
:return: :return:
""" """
@ -413,7 +417,6 @@ def are_lists_identical(source_list, target_list, ignore_whitespaces,
if isinstance(source_list[index], dict): if isinstance(source_list[index], dict):
if not are_dictionaries_identical(source_list[index], if not are_dictionaries_identical(source_list[index],
target_list[index], target_list[index],
ignore_whitespaces,
ignore_keys): ignore_keys):
return False return False
else: else:
@ -422,17 +425,17 @@ def are_lists_identical(source_list, target_list, ignore_whitespaces,
return True return True
def are_dictionaries_identical(source_dict, target_dict, ignore_whitespaces, def are_dictionaries_identical(source_dict, target_dict, ignore_keys):
ignore_keys):
""" """
This function is used to recursively compare two dictionaries with This function is used to recursively compare two dictionaries with
same keys. same keys.
:param source_dict: source dict :param source_dict: source dict
:param target_dict: target dict :param target_dict: target dict
:param ignore_whitespaces: If set to True then ignore whitespaces
:param ignore_keys: ignore keys to compare :param ignore_keys: ignore keys to compare
:return: :return:
""" """
pref = Preferences.module('schema_diff')
ignore_whitespaces = pref.preference('ignore_whitespaces').get()
src_keys = set(source_dict.keys()) src_keys = set(source_dict.keys())
tar_keys = set(target_dict.keys()) tar_keys = set(target_dict.keys())
@ -466,7 +469,6 @@ def are_dictionaries_identical(source_dict, target_dict, ignore_whitespaces,
if isinstance(source_dict[key], dict): if isinstance(source_dict[key], dict):
if not are_dictionaries_identical(source_dict[key], if not are_dictionaries_identical(source_dict[key],
target_dict[key], target_dict[key],
ignore_whitespaces,
ignore_keys): ignore_keys):
return False return False
elif isinstance(source_dict[key], list): elif isinstance(source_dict[key], list):
@ -476,7 +478,6 @@ def are_dictionaries_identical(source_dict, target_dict, ignore_whitespaces,
target_dict[key]) target_dict[key])
# Compare the source and target lists # Compare the source and target lists
if not are_lists_identical(source_dict[key], target_dict[key], if not are_lists_identical(source_dict[key], target_dict[key],
ignore_whitespaces,
ignore_keys): ignore_keys):
return False return False
else: else: