Короткий ответ
Единственного правильного решения нет: можно добавить явные assert на количество строк до/после merge и validate на тип связи в каждом критичном месте пайплайна, либо выстроить более общий слой автоматических проверок инвариантов данных — выбор зависит от того, сколько таких критичных мест в пайплайне и насколько высока цена ошибки.
Как это работает подробнее
точечная защита — это assert len(result) == len(left) сразу после merge, где ожидается связь один-к-одному или один-ко-многим без изменения числа "главных" записей, плюс validate в самом merge; более общая защита — отдельный модуль проверок данных (data quality checks), который прогоняется после каждого значимого шага пайплайна и логирует/останавливает выполнение при нарушении инварианта.
Пример кода
Пример на Python
import pandas as pd
def safe_merge(left: pd.DataFrame, right: pd.DataFrame, on: str) -> pd.DataFrame:
before = len(left)
merged = pd.merge(left, right, on=on, how='left', validate='many_to_one')
assert len(merged) == before, f'Row count changed after merge: {before} -> {len(merged)}'
return mergedЧто использовать на практике
- На практике. для критичных финансовых и управленческих отчётов стоит добавлять проверки в тех местах, где исторически уже случались инциденты, и в местах, где ключ объединения потенциально может перестать быть уникальным (например, справочник пользователей, в который теоретически может попасть дубль); проверки должны явно и громко падать (не просто печатать warning), чтобы ошибка не доходила до бизнес-пользователей незамеченной.
- Проверка. safe_merge либо вернёт результат с гарантированно тем же числом строк, что и до merge, либо явно упадёт с понятной ошибкой до того, как искажённые данные попадут в отчёт для бизнеса.
Подводные камни
- Частые ошибки. добавляют проверки только в том месте пайплайна, где уже был инцидент, игнорируя структурно похожие места, где та же ошибка может повториться с другим ключом объединения; делают проверки настолько строгими и многочисленными, что они начинают ложно срабатывать на легитимные редкие случаи, из-за чего со временем их отключают целиком, а не донастраивают.