What Changed Overnight
A medium Python interview practice problem on DataDriven. Write the Python and run it against test cases, with instant feedback.
- Domain
- Python
- Difficulty
- medium
- Seniority
- L4
- Asked in
Problem
A migration ran overnight, and you have the table's columns from before it (old_schema) and after (new_schema), each a list of {'name', 'type'} dicts. Return which columns were added, which were removed, and which kept their name but changed type.
Schema from yesterday vs today. Something changed.
Example 1
Input:
new_schema = [{"name":"id","type":"BIGINT"},{"name":"age","type":"INT"},{"name":"phone","type":"VARCHAR"}], old_schema = [{"name":"id","type":"INT"},{"name":"email","type":"VARCHAR"},{"name":"age","type":"INT"}]Output:
{"added":["phone"],"removed":["email"],"type_changed":[{"name":"id","new_type":"BIGINT","old_type":"INT"}]}Example 2
Input:
new_schema = [{"name":"zip","type":"VARCHAR"},{"name":"city","type":"VARCHAR"},{"name":"id","type":"BIGINT"},{"name":"score","type":"FLOAT"}], old_schema = [{"name":"id","type":"INT"},{"name":"city","type":"TEXT"},{"name":"country","type":"VARCHAR"}]Output:
{"added":["score","zip"],"removed":["country"],"type_changed":[{"name":"city","new_type":"VARCHAR","old_type":"TEXT"},{"name":"id","new_type":"BIGINT","old_type":"INT"}]}Worked solution and explanation
Why this problem exists in real interviews
This is column-by-column matching wearing a schema-drift costume. The trap: almost everyone walks the two lists and compares them position-by-position, which reports every column as added and removed the moment someone reorders them. The real skill is indexing each schema by name first, then doing set math on the keysets so order stops mattering and the whole thing runs O(n+m) instead of O(n*m).
Break down the requirements
Step 1: Index both schemas by column name
Build a dict mapping column name to column type for each schema. This is the move that makes ordering irrelevant and lookups O(1).
Step 2: Find added and removed columns
Columns whose names are in new but not old are added; the reverse are removed. Subtracting the two keysets gives both directly. Sort each name list ascending.
Step 3: Find columns with changed types
For names present in both keysets, compare their types and emit a {'name', 'new_type', 'old_type'} dict for each mismatch, walked in sorted name order so the result is already ordered.
The solution
def schema_diff(new_schema, old_schema):
new_map = {col['name']: col['type'] for col in new_schema}
old_map = {col['name']: col['type'] for col in old_schema}
new_names = set(new_map)
old_names = set(old_map)
added = sorted(new_names - old_names)
removed = sorted(old_names - new_names)
type_changed = []
for name in sorted(new_names & old_names):
if new_map[name] != old_map[name]:
type_changed.append({
'name': name,
'new_type': new_map[name],
'old_type': old_map[name],
})
return {
'added': added,
'removed': removed,
'type_changed': type_changed,
}Common follow-up questions
- How would you detect column renames? (Tests heuristic matching: same type, similar position, only one candidate.)
- What if schemas had nullable flags and default values? (Tests extending the comparison to additional column attributes.)
- How would you auto-generate ALTER TABLE statements from the diff? (Tests translating diff categories to DDL: ADD COLUMN, DROP COLUMN, ALTER COLUMN TYPE.)
- What if there were hundreds of schema versions to compare? (Tests pairwise diff chaining or baseline comparison strategies.)