update
Some checks are pending
Setup Native Action / native (3.12.7) (push) Waiting to run
Setup Native Action / docker (3.12.7) (push) Waiting to run

This commit is contained in:
KaySar12 2025-03-19 18:15:03 +07:00
parent 9086b4d26d
commit 0b92875c00

View File

@ -73,10 +73,13 @@ db_name = args.db_name
base_model = args.base_model base_model = args.base_model
domain_str = args.domain domain_str = args.domain
process_size = args.process_size process_size = args.process_size
OK = 0
FAIL = 1
INFO = 2
NOTICE = 3
# Odoo connection setup # Odoo connection setup
odoo = odoorpc.ODOO(HOST, port=PORT) odoo = odoorpc.ODOO(HOST, port=PORT)
color_log.Show(2, ("Available databases:", odoo.db.list())) color_log.Show(INFO, ("Available databases:", odoo.db.list()))
# Login to Odoo # Login to Odoo
try: try:
@ -86,19 +89,25 @@ try:
f"Connected to Odoo at {HOST}:{PORT}, Database: {db_name}, Model: {base_model}", f"Connected to Odoo at {HOST}:{PORT}, Database: {db_name}, Model: {base_model}",
) )
except Exception as e: except Exception as e:
color_log.Show(1, f"Fail to Connect to Odoo Server {e}") color_log.Show(FAIL, f"Fail to Connect to Odoo Server {e}")
exit(1) exit(1)
# Convert DOMAIN from string to list # Convert DOMAIN from string to list
try: try:
domain_filter = ast.literal_eval(domain_str) domain_filter = ast.literal_eval(domain_str)
except Exception as e: except Exception as e:
color_log.Show(3, f"Invalid DOMAIN format: {e}") color_log.Show(FAIL, f"Invalid DOMAIN format: {e}")
exit(1) exit(1)
skipped_models_cache = set() # Cache to store skipped models
def fetch_related_fields_for_model(model, base_model): def fetch_related_fields_for_model(model, base_model):
"""Fetch related fields for a single model.""" """Fetch related fields for a single model with caching for skipped models."""
if model in skipped_models_cache:
color_log.Show(NOTICE, f"Skipping cached model {model}")
return {}
related_fields = {} related_fields = {}
try: try:
fields = odoo.env[model].fields_get() fields = odoo.env[model].fields_get()
@ -109,10 +118,10 @@ def fetch_related_fields_for_model(model, base_model):
): ):
related_fields.setdefault(model, []).append(field_name) related_fields.setdefault(model, []).append(field_name)
except Exception as e: except Exception as e:
color_log.Show(3, f"Skipping model {model}: {e}") color_log.Show(NOTICE, f"Skipping model {model}: {e}")
skipped_models_cache.add(model) # Add to cache if an error occurs
return related_fields return related_fields
# Function to fetch related models # Function to fetch related models
def get_related_fields(db_name, base_model): def get_related_fields(db_name, base_model):
"""Fetch related fields for a given model using multiprocessing.""" """Fetch related fields for a given model using multiprocessing."""
@ -123,7 +132,7 @@ def get_related_fields(db_name, base_model):
related_models = json.load(f) related_models = json.load(f)
return related_models return related_models
color_log.Show(2, f"Fetching related models for {base_model} from Odoo...") color_log.Show(INFO, f"Fetching related models for {base_model} from Odoo...")
related_models = {} related_models = {}
try: try:
@ -150,7 +159,7 @@ def get_related_fields(db_name, base_model):
return related_models return related_models
except Exception as e: except Exception as e:
color_log.Show(3, f"Error fetching related models: {e}") color_log.Show(FAIL, f"Error fetching related models: {e}")
return {} return {}
@ -186,12 +195,15 @@ def delete_records_cascade(
if related_ids: if related_ids:
stack.append((related_model, related_ids)) stack.append((related_model, related_ids))
has_dependents = True has_dependents = True
print( color_log.Show(
f"{process_count}: Found {len(related_ids)} related records in {related_model} ({field})" 3,
f"{process_count}: Found {len(related_ids)} related records in {related_model} ({field})",
) )
process_count += 1 process_count += 1
except odoorpc.error.RPCError as e: except odoorpc.error.RPCError as e:
print(f"Access denied for model {related_model}: {e}") color_log.Show(
1, f"Access denied for model {related_model}: {e}"
)
continue continue
if not has_dependents: if not has_dependents:
@ -204,17 +216,17 @@ def delete_records_cascade(
try: try:
if del_ids: if del_ids:
odoo.env[del_model].browse(del_ids).unlink() odoo.env[del_model].browse(del_ids).unlink()
color_log.Show(0, f"Deleted {len(del_ids)} records from {del_model}") color_log.Show(OK, f"Deleted {len(del_ids)} records from {del_model}")
except Exception as e: except Exception as e:
color_log.Show(3, f"Error deleting {del_model} records: {e}") color_log.Show(FAIL, f"Error deleting {del_model} records: {e}")
# Now delete the main records after all dependencies are gone # Now delete the main records after all dependencies are gone
try: try:
if record_ids: if record_ids:
odoo.env.browse(record_ids).unlink() odoo.env.browse(record_ids).unlink()
color_log.Show(0, f"Deleted {len(record_ids)} records from {model_name}") color_log.Show(OK, f"Deleted {len(record_ids)} records from {model_name}")
except Exception as e: except Exception as e:
color_log.Show(3, f"Error deleting {model_name} records: {e}") color_log.Show(FAIL, f"Error deleting {model_name} records: {e}")
# Function to delete records in parallel # Function to delete records in parallel
@ -237,22 +249,22 @@ def process_batch(batch, model_name, process_count, related_models):
model.browse(record_id).write({"active": False}) model.browse(record_id).write({"active": False})
archived_count += 1 archived_count += 1
color_log.Show( color_log.Show(
2, f"{process_count}: Archived {model_name} ID {record_id}" INFO, f"{process_count}: Archived {model_name} ID {record_id}"
) )
else: else:
model.unlink([record_id]) model.unlink([record_id])
deleted_count += 1 deleted_count += 1
color_log.Show( color_log.Show(
2, f"{process_count}: Deleted {model_name} ID {record_id}" INFO, f"{process_count}: Deleted {model_name} ID {record_id}"
) )
except Exception as e: except Exception as e:
skipped_count += 1 skipped_count += 1
color_log.Show( color_log.Show(
3, f"{process_count}: Skipped {model_name} ID {record_id}: {e}" INFO, f"{process_count}: Skipped {model_name} ID {record_id}: {e}"
) )
color_log.Show( color_log.Show(
0, OK,
f"{process_count}: {model_name} - Deleted: {deleted_count}, Archived: {archived_count}, Skipped: {skipped_count}.", f"{process_count}: {model_name} - Deleted: {deleted_count}, Archived: {archived_count}, Skipped: {skipped_count}.",
) )
@ -261,12 +273,12 @@ def process_batch(batch, model_name, process_count, related_models):
def main(): def main():
"""Main function to fetch records and process them in parallel.""" """Main function to fetch records and process them in parallel."""
model = odoo.env[base_model] model = odoo.env[base_model]
color_log.Show(2, f"{domain_filter}") color_log.Show(INFO, f"{domain_filter}")
record_ids = model.search(domain_filter) record_ids = model.search(domain_filter)
if not record_ids: if not record_ids:
color_log.Show( color_log.Show(
1, f"No records found for model {base_model} with the given domain." FAIL, f"No records found for model {base_model} with the given domain."
) )
return return
@ -301,7 +313,7 @@ def main():
for process in processes: for process in processes:
process.join() process.join()
color_log.Show(0, "Record deletion process completed.") color_log.Show(OK, "Record deletion process completed.")
if __name__ == "__main__": if __name__ == "__main__":