Data Comparison
Relevant source files
The following files were used as context for generating this wiki page:
Data Comparison in the flext-ldap project provides the logic necessary to identify differences between LDAP entries, typically between a local LDIF source and a remote LDAP server. It is a critical component for synchronization workflows, enabling the system to generate precise MODIFY operations (REPLACE or DELETE) rather than re-uploading entire entries. Sources: src/flext_ldap/_utilities/comparison.py, tests/unit/test_sync.py
The module focuses on normalizing LDAP attribute values (handling case-insensitivity and multi-valued attributes) to ensure that comparison results are stable and accurate. It integrates closely with the sync services to provide metadata regarding entry changes, such as DN modifications or attribute updates. Sources: src/flext_ldap/_utilities/comparison.py:27-35, tests/unit/test_models_sync.py:46-56
Architecture and Component Flow
The comparison logic is primarily encapsulated in the FlextLdapUtilitiesComparison class. It inherits from normalization utilities to handle the specific string formatting requirements of LDAP. Sources: src/flext_ldap/_utilities/comparison.py:10-12
Comparison Process Flow
The following diagram illustrates the logical flow when comparing an existing LDAP entry against a target (new) entry:
The comparison logic iterates through all attributes in the target entry to find differences with the existing entry, then identifies attributes present in the existing entry but missing from the new one to mark them for deletion. Sources: src/flext_ldap/_utilities/comparison.py:90-112
Key Comparison Functions
| Function | Description |
|---|---|
compare_entries | The high-level entry point that compares two p.Ldif.Entry objects and returns a result containing OperationChanges. |
process_new_attributes | Iterates through new attributes and creates REPLACE operations if values differ from existing ones. |
process_deleted_attributes | Identifies attributes that exist in the destination but not the source, creating DELETE operations. |
find_existing_values | Performs a case-insensitive lookup of attribute values within an attribute mapping. |
normalize_value_set | Converts a sequence of attribute values into a set of lowercase strings for stable comparison. |
Sources: src/flext_ldap/_utilities/comparison.py:27-112
Attribute Normalization Logic
LDAP attributes are often case-insensitive and can contain multiple values. The comparison engine handles this by transforming values into a standardized set:
@staticmethod
def normalize_value_set(values: t.StrSequence) -> set[str]:
"""Normalize LDAP attribute values for stable comparison."""
return {value.lower() for value in values if value}
Sources: src/flext_ldap/_utilities/comparison.py:37-40
Synchronization Metadata
When comparisons are performed during sync phases, the system tracks the differences using a ConversionMetadata model. This model records if the Distinguished Name (DN) has changed and maintains lists of attributes that were removed or specially encoded. Sources: tests/unit/test_models_sync.py:46-56
Data Structure: OperationChanges
The output of a comparison is the OperationChanges type, which maps attribute names to a sequence of operations (REPLACE or DELETE).
# Example of the structure returned by compare_entries
changes = {
"cn": [(ModifyOperation.REPLACE, ["new_value"])],
"description": [(ModifyOperation.DELETE, [])]
}
Sources: src/flext_ldap/_utilities/comparison.py:65-67, tests/unit/test_ldap3_adapter_helpers.py:236-240
Integration with Sync Phases
Comparison is a prerequisite for the "Upsert" logic within synchronization. If a comparison determines that an entry is identical to the server version, the operation may be skipped. If differences are found, the UpsertResult reflects the specific OperationType performed (e.g., MODIFY). Sources: tests/unit/test_models_sync.py:11-30
Usage in Testing and Validation
The comparison logic is strictly validated via unit tests that ensure:
- Case-Insensitivity: Comparing "ADMIN" and "admin" results in no change. Sources: tests/unit/test_utilities.py:348-360
- Missing Attributes: Handling cases where the existing or new entry has no attributes. Sources: src/flext_ldap/_utilities/comparison.py:97-106
- Ignored Attributes: Certain operational attributes (defined in
c.Ldif.OperationalAttributes.IGNORE_SET) are skipped during comparison to prevent errors with server-managed data. Sources: src/flext_ldap/_utilities/comparison.py:82-84
Summary
The Data Comparison module provides the necessary intelligence for efficient LDAP updates. By normalizing attribute values and identifying precise delta changes, it enables the flext-ldap library to perform targeted MODIFY operations, ensuring data consistency while minimizing network overhead during large-scale synchronization tasks. Sources: src/flext_ldap/_utilities/comparison.py, tests/unit/test_models_sync.py