Skip to content
This repository was archived by the owner on May 17, 2024. It is now read-only.

Commit c982b1e

Browse files
committed
rewrite type hitns to dataclasses to support Python 3.7
1 parent 98d0de5 commit c982b1e

File tree

2 files changed

+110
-84
lines changed

2 files changed

+110
-84
lines changed

data_diff/format.py

Lines changed: 108 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,14 @@
11
import collections
2+
from typing import Any, Optional, List, Dict, Tuple
23

3-
from data_diff.diff_tables import DiffResultWrapper
4-
from typing import TypedDict, Any, Optional, List, Dict, Tuple
5-
6-
4+
from runtype import dataclass
75

8-
class ColumnsDiff(TypedDict):
9-
removed: List[str]
10-
added: List[str]
11-
changed: List[str]
6+
from data_diff.diff_tables import DiffResultWrapper
127

138

149
def jsonify(diff: DiffResultWrapper,
1510
with_summary: bool = False,
16-
with_columns: Optional[ColumnsDiff] = None) -> 'JsonDiff':
11+
with_columns: Optional[Dict[str, List[str]]] = None) -> 'JsonDiff':
1712
"""
1813
Converts the diff result into a JSON-serializable format.
1914
Optionally add stats summary and schema diff.
@@ -49,8 +44,7 @@ def jsonify(diff: DiffResultWrapper,
4944

5045
columns = None
5146
if with_columns:
52-
added, removed, changed = with_columns['added'], with_columns['removed'], with_columns['changed']
53-
columns = _jsonify_columns_diff(added, removed, changed)
47+
columns = _jsonify_columns_diff(with_columns)
5448

5549
is_different = bool(
5650
t1_exclusive_rows
@@ -62,44 +56,34 @@ def jsonify(diff: DiffResultWrapper,
6256
or with_columns['changed']
6357
)
6458
)
65-
return {
66-
'isDifferent': is_different,
67-
'table1': list(table1.table_path),
68-
'table2': list(table2.table_path),
69-
'rows': {
70-
'exclusive': {
71-
'table1': t1_exclusive_rows_jsonified,
72-
'table2': t2_exclusive_rows_jsonified,
73-
},
74-
'diff': diff_rows_jsonified,
75-
},
76-
'summary': summary,
77-
'columns': columns,
78-
}
79-
80-
class JsonDiff(TypedDict):
81-
table1: List[str]
82-
table2: List[str]
83-
rows: TypedDict('Rows', {
84-
'exclusive': TypedDict('Exclusive', {
85-
'table1': List['JsonExclusiveRow'],
86-
'table2': List['JsonExclusiveRow'],
87-
}),
88-
'diff': List['JsonDiffRow'],
89-
})
90-
summary: Optional['JsonDiffSummary' ]
91-
columns: Optional['JsonColumnsSummary']
92-
93-
94-
95-
class JsonExclusiveRowValue(TypedDict):
59+
return JsonDiff(
60+
isDifferent=is_different,
61+
table1=list(table1.table_path),
62+
table2=list(table2.table_path),
63+
rows=RowsDiff(
64+
exclusive=ExclusiveDiff(
65+
table1=t1_exclusive_rows_jsonified,
66+
table2=t2_exclusive_rows_jsonified
67+
),
68+
diff=diff_rows_jsonified,
69+
),
70+
summary=summary,
71+
columns=columns,
72+
).json()
73+
74+
75+
76+
@dataclass
77+
class JsonExclusiveRowValue:
9678
"""
9779
Value of a single column in a row
9880
"""
9981
isPK: bool
10082
value: Any
10183

102-
class JsonDiffRowValue(TypedDict):
84+
85+
@dataclass
86+
class JsonDiffRowValue:
10387
"""
10488
Pair of diffed values for 2 rows with equal PKs
10589
"""
@@ -109,35 +93,72 @@ class JsonDiffRowValue(TypedDict):
10993
isPK: bool
11094

11195

112-
JsonDiffRow = Dict[str, JsonDiffRowValue]
113-
JsonExclusiveRow = Dict[str, JsonExclusiveRowValue]
114-
115-
116-
class JsonDiffSummary(TypedDict):
117-
rows: TypedDict('Rows', {
118-
'total': TypedDict('Total', {
119-
'table1': int,
120-
'table2': int,
121-
}),
122-
'exclusive': TypedDict('Exclusive', {
123-
'table1': int,
124-
'table2': int,
125-
}),
126-
'updated': int,
127-
'unchanged': int,
128-
})
129-
stats: TypedDict('Stats', {
130-
'diffCounts': Dict[str, int],
131-
})
132-
133-
class JsonColumnsSummary(TypedDict):
134-
exclusive: TypedDict('Exclusive', {
135-
'table1': List[str],
136-
'table2': List[str],
137-
})
96+
@dataclass
97+
class Total:
98+
table1: int
99+
table2: int
100+
101+
102+
@dataclass
103+
class ExclusiveRows:
104+
table1: int
105+
table2: int
106+
107+
108+
@dataclass
109+
class Rows:
110+
total: Total
111+
exclusive: ExclusiveRows
112+
updated: int
113+
unchanged: int
114+
115+
116+
@dataclass
117+
class Stats:
118+
diffCounts: Dict[str, int]
119+
120+
121+
@dataclass
122+
class JsonDiffSummary:
123+
rows: Rows
124+
stats: Stats
125+
126+
127+
@dataclass
128+
class ExclusiveColumns:
129+
table1: List[str]
130+
table2: List[str]
131+
132+
133+
@dataclass
134+
class JsonColumnsSummary:
135+
exclusive: ExclusiveColumns
138136
typeChanged: List[str]
139137

140138

139+
@dataclass
140+
class ExclusiveDiff:
141+
table1: List[Dict[str, JsonExclusiveRowValue]]
142+
table2: List[Dict[str, JsonExclusiveRowValue]]
143+
144+
145+
@dataclass
146+
class RowsDiff:
147+
exclusive: ExclusiveDiff
148+
diff: List[Dict[str, JsonDiffRowValue]]
149+
150+
151+
@dataclass
152+
class JsonDiff:
153+
isDifferent: bool
154+
table1: List[str]
155+
table2: List[str]
156+
rows: RowsDiff
157+
summary: Optional[JsonDiffSummary]
158+
columns: Optional[JsonColumnsSummary]
159+
160+
version: str = '1.0.0'
161+
141162

142163
def _group_rows(diff_info: DiffResultWrapper,
143164
schema: List[str]) -> Tuple[List[Dict[str, Any]], List[Dict[str, Any]], List[Dict[str, Any]]]:
@@ -162,7 +183,7 @@ def _group_rows(diff_info: DiffResultWrapper,
162183
return t1_exclusive_rows, t2_exclusive_rows, diff_rows
163184

164185

165-
def _jsonify_diff(row: Dict[str, Any], key_columns: List[str]) -> JsonDiffRowValue:
186+
def _jsonify_diff(row: Dict[str, Any], key_columns: List[str]) -> Dict[str, JsonDiffRowValue]:
166187
columns = collections.defaultdict(dict)
167188
for field, value in row.items():
168189
if field in ('is_exclusive_a', 'is_exclusive_b'):
@@ -182,10 +203,13 @@ def _jsonify_diff(row: Dict[str, Any], key_columns: List[str]) -> JsonDiffRowVal
182203
columns[column_name]['table2'] = value
183204
columns[column_name]['isPK'] = column_name in key_columns
184205

185-
return columns
206+
return {
207+
column: JsonDiffRowValue(**data)
208+
for column, data in columns.items()
209+
}
186210

187211

188-
def _jsonify_exclusive(row: Dict[str, Any], key_columns: List[str]) -> JsonExclusiveRow:
212+
def _jsonify_exclusive(row: Dict[str, Any], key_columns: List[str]) -> Dict[str, JsonExclusiveRowValue]:
189213
columns = collections.defaultdict(dict)
190214
for field, value in row.items():
191215
if field in ('is_exclusive_a', 'is_exclusive_b'):
@@ -200,7 +224,10 @@ def _jsonify_exclusive(row: Dict[str, Any], key_columns: List[str]) -> JsonExclu
200224
column_name = field.replace('_a', '')
201225
columns[column_name]['isPK'] = column_name in key_columns
202226
columns[column_name]['value'] = value
203-
return columns
227+
return {
228+
column: JsonExclusiveRowValue(**data)
229+
for column, data in columns.items()
230+
}
204231

205232

206233
def _jsonify_diff_summary(stats_dict: dict) -> JsonDiffSummary:
@@ -223,14 +250,11 @@ def _jsonify_diff_summary(stats_dict: dict) -> JsonDiffSummary:
223250
}
224251

225252

226-
def _jsonify_columns_diff(added_columns: List[str],
227-
removed_columns: List[str],
228-
changed_columns: List[str]) -> JsonColumnsSummary:
229-
columns = {
230-
'exclusive': {
231-
'table2': list(added_columns),
232-
'table1': list(removed_columns),
233-
},
234-
'typeChanged': list(changed_columns),
235-
}
236-
return columns
253+
def _jsonify_columns_diff(columns_diff: Dict[str, List[str]]) -> JsonColumnsSummary:
254+
return JsonColumnsSummary(
255+
exclusive= ExclusiveColumns(
256+
table2= list(columns_diff.get('added', [])),
257+
table1= list(columns_diff.get('removed', [])),
258+
),
259+
typeChanged=list(columns_diff.get('changed', [])),
260+
)

tests/test_format.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ def test_jsonify_diff(self):
3030
)
3131
json_diff = jsonify(diff)
3232
self.assertEqual(json_diff, {
33+
'version': '1.0.0',
3334
'isDifferent': True,
3435
'table1': ['db', 'schema', 'table1'],
3536
'table2': ['db', 'schema', 'table2'],
@@ -79,6 +80,7 @@ def test_jsonify_diff_no_difeference(self):
7980
)
8081
json_diff = jsonify(diff)
8182
self.assertEqual(json_diff, {
83+
'version': '1.0.0',
8284
'isDifferent': False,
8385
'table1': ['db', 'schema', 'table1'],
8486
'table2': ['db', 'schema', 'table2'],

0 commit comments

Comments
 (0)