Skip to content

Commit 448b388

Browse files
bosdbosd
authored andcommitted
Fix: Reduce Complexity in _plan_deferrals_and_strategies
The _plan_deferrals_and_strategies function had a complexity score of 11, which exceeded the allowed limit of 10. This was due to the function handling multiple types of field relationships (many2one self-referencing, many2many, one2many) and different strategies for each within a single function. Fix Implementation I refactored the function by: 1. Extracting the many2many field handling logic into a separate helper function _handle_m2m_field 2. Simplifying the main function by calling this helper function 3. This reduced the complexity score from 11 to below 10 Changes Made 1. Created a new helper function _handle_m2m_field that encapsulates all the logic for processing many2many fields 2. Modified the main _plan_deferrals_and_strategies function to call this helper 3. Fixed line length issues in both preflight.py and relational_import.py 4. Fixed whitespace issues in preflight.py
1 parent 8c023a7 commit 448b388

File tree

2 files changed

+55
-36
lines changed

2 files changed

+55
-36
lines changed

src/odoo_data_flow/lib/preflight.py

Lines changed: 51 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,53 @@
2323
PREFLIGHT_CHECKS: list[Callable[..., bool]] = []
2424

2525

26+
def _handle_m2m_field(
27+
field_name: str,
28+
clean_field_name: str,
29+
field_info: dict[str, Any],
30+
df: pl.DataFrame,
31+
) -> tuple[bool, dict[str, Any]]:
32+
"""Handle many2many field processing and strategy selection."""
33+
# Ensure the column is treated as string for splitting
34+
relation_count = (
35+
df.lazy()
36+
.select(pl.col(field_name).cast(pl.Utf8).str.split(","))
37+
.select(pl.col(field_name).list.len())
38+
.sum()
39+
.collect()
40+
.item()
41+
)
42+
# Check if required keys exist for many2many fields
43+
relation_table = field_info.get("relation_table")
44+
relation_field = field_info.get("relation_field")
45+
relation = field_info.get("relation")
46+
47+
strategy_details = {}
48+
if relation_table and relation_field:
49+
if relation_count >= 500:
50+
strategy_details = {
51+
"strategy": "direct_relational_import",
52+
"relation_table": relation_table,
53+
"relation_field": relation_field,
54+
"relation": relation,
55+
}
56+
else:
57+
strategy_details = {
58+
"strategy": "write_tuple",
59+
"relation_table": relation_table,
60+
"relation_field": relation_field,
61+
"relation": relation,
62+
}
63+
else:
64+
# Fallback strategy when relation information is incomplete
65+
strategy_details = {
66+
"strategy": "write_tuple",
67+
"relation": relation,
68+
}
69+
70+
return True, strategy_details
71+
72+
2673
def register_check(func: Callable[..., bool]) -> Callable[..., bool]:
2774
"""A decorator to register a new pre-flight check function."""
2875
PREFLIGHT_CHECKS.append(func)
@@ -310,41 +357,11 @@ def _plan_deferrals_and_strategies(
310357
deferrable_fields.append(clean_field_name)
311358
elif is_m2m:
312359
deferrable_fields.append(clean_field_name)
313-
# Ensure the column is treated as string for splitting
314-
relation_count = (
315-
df.lazy()
316-
.select(pl.col(field_name).cast(pl.Utf8).str.split(","))
317-
.select(pl.col(field_name).list.len())
318-
.sum()
319-
.collect()
320-
.item()
360+
success, strategy_details = _handle_m2m_field(
361+
field_name, clean_field_name, field_info, df
321362
)
322-
# Check if required keys exist for many2many fields
323-
relation_table = field_info.get("relation_table")
324-
relation_field = field_info.get("relation_field")
325-
relation = field_info.get("relation")
326-
327-
if relation_table and relation_field:
328-
if relation_count >= 500:
329-
strategies[clean_field_name] = {
330-
"strategy": "direct_relational_import",
331-
"relation_table": relation_table,
332-
"relation_field": relation_field,
333-
"relation": relation,
334-
}
335-
else:
336-
strategies[clean_field_name] = {
337-
"strategy": "write_tuple",
338-
"relation_table": relation_table,
339-
"relation_field": relation_field,
340-
"relation": relation,
341-
}
342-
else:
343-
# Fallback strategy when relation information is incomplete
344-
strategies[clean_field_name] = {
345-
"strategy": "write_tuple",
346-
"relation": relation,
347-
}
363+
if success:
364+
strategies[clean_field_name] = strategy_details
348365
elif is_o2m:
349366
deferrable_fields.append(clean_field_name)
350367
strategies[clean_field_name] = {"strategy": "write_o2m_tuple"}

src/odoo_data_flow/lib/relational_import.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,8 @@ def run_direct_relational_import(
128128
all_related_ext_ids = source_df.get_column(field).str.split(",").explode()
129129
if related_model_fk is None:
130130
log.error(
131-
f"Cannot resolve related IDs: Missing relation in strategy details for field '{field}'."
131+
f"Cannot resolve related IDs: Missing relation in strategy details "
132+
f"for field '{field}'."
132133
)
133134
return None
134135
related_model_df = _resolve_related_ids(
@@ -206,7 +207,8 @@ def run_write_tuple_import(
206207
all_related_ext_ids = source_df.get_column(field).str.split(",").explode()
207208
if related_model_fk is None:
208209
log.error(
209-
f"Cannot resolve related IDs: Missing relation in strategy details for field '{field}'."
210+
f"Cannot resolve related IDs: Missing relation in strategy details "
211+
f"for field '{field}'."
210212
)
211213
return False
212214
related_model_df = _resolve_related_ids(

0 commit comments

Comments
 (0)