mirror of
https://github.com/frappe/erpnext.git
synced 2026-08-14 07:01:56 +00:00
refactor(postgres): memoise representative lines with frappe's request_cache
Three helpers each managed their own dictionary on frappe.local, duplicating cache lifecycle and key handling. @request_cache does the same thing centrally and is cleared with the request, so the copies cannot drift apart. Behaviour is unchanged: the decorator keys on the call arguments, which are the same tuple each hand-rolled key was built from.
This commit is contained in:
@@ -11,6 +11,7 @@ from frappe.model.document import Document
|
||||
from frappe.query_builder import Field
|
||||
from frappe.query_builder.functions import Count, IfNull, Max, Min, NullIf, Sum
|
||||
from frappe.utils import cint, cstr, flt, get_link_to_form, parse_json
|
||||
from frappe.utils.caching import request_cache
|
||||
from frappe.website.website_generator import WebsiteGenerator
|
||||
|
||||
import erpnext
|
||||
@@ -1253,17 +1254,10 @@ def _apply_representative_lines(rows, doctype, bom, keys):
|
||||
row[column] = line.get(column)
|
||||
|
||||
|
||||
@request_cache
|
||||
def _representative_lines(doctype, bom, keys, columns):
|
||||
"""Cached per request: get_bom_items_as_dict recurses through phantom BOMs, and the same
|
||||
sub-BOM is commonly reached more than once."""
|
||||
cache = getattr(frappe.local, "_bom_representative_lines", None)
|
||||
if cache is None:
|
||||
cache = frappe.local._bom_representative_lines = {}
|
||||
|
||||
cache_key = (doctype, bom, keys, columns)
|
||||
if cache_key in cache:
|
||||
return cache[cache_key]
|
||||
|
||||
representative = {}
|
||||
for line in frappe.get_all(
|
||||
doctype,
|
||||
@@ -1273,7 +1267,6 @@ def _representative_lines(doctype, bom, keys, columns):
|
||||
):
|
||||
representative.setdefault(tuple(line.get(key) for key in keys), line)
|
||||
|
||||
cache[cache_key] = representative
|
||||
return representative
|
||||
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
import frappe
|
||||
from frappe.query_builder.functions import Count, IfNull, Max, Min, Sum
|
||||
from frappe.utils.caching import request_cache
|
||||
|
||||
from erpnext.manufacturing.doctype.production_plan.services.planning_queries import get_uom_conversion_factor
|
||||
|
||||
@@ -67,16 +68,9 @@ def _apply_representative_lines(rows, doctype, bom_no, keys, include_non_stock_i
|
||||
row.source_warehouse = line.source_warehouse
|
||||
|
||||
|
||||
@request_cache
|
||||
def _representative_lines(doctype, bom_no, keys, include_non_stock_items):
|
||||
"""Cached per request: the explosion recurses and commonly revisits the same sub-BOM."""
|
||||
cache = getattr(frappe.local, "_bom_explosion_representative_lines", None)
|
||||
if cache is None:
|
||||
cache = frappe.local._bom_explosion_representative_lines = {}
|
||||
|
||||
cache_key = (doctype, bom_no, keys, include_non_stock_items)
|
||||
if cache_key in cache:
|
||||
return cache[cache_key]
|
||||
|
||||
# only BOM Item carries is_phantom_item, and only its query ORs the phantom flag into the stock
|
||||
# filter; the explosion table has neither
|
||||
filters_phantom = doctype == "BOM Item"
|
||||
@@ -112,7 +106,6 @@ def _representative_lines(doctype, bom_no, keys, include_non_stock_items):
|
||||
for line in lines:
|
||||
representative.setdefault(tuple(line.get(key) for key in keys), line)
|
||||
|
||||
cache[cache_key] = representative
|
||||
return representative
|
||||
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
import frappe
|
||||
from frappe.query_builder.functions import Count, IfNull, Max, Sum
|
||||
from frappe.utils import flt
|
||||
from frappe.utils.caching import request_cache
|
||||
|
||||
from erpnext.manufacturing.doctype.bom.bom import get_children as get_bom_children
|
||||
from erpnext.manufacturing.doctype.production_plan.services.planning_queries import (
|
||||
@@ -207,15 +208,9 @@ def _apply_representative_lines(rows, bom_no):
|
||||
row.source_warehouse = line.source_warehouse
|
||||
|
||||
|
||||
@request_cache
|
||||
def _representative_lines(bom_no, keys):
|
||||
"""Cached per request: sub-assembly resolution recurses and revisits the same BOM."""
|
||||
cache = getattr(frappe.local, "_sub_assembly_representative_lines", None)
|
||||
if cache is None:
|
||||
cache = frappe.local._sub_assembly_representative_lines = {}
|
||||
|
||||
if bom_no in cache:
|
||||
return cache[bom_no]
|
||||
|
||||
representative = {}
|
||||
for line in frappe.get_all(
|
||||
"BOM Item",
|
||||
@@ -230,7 +225,6 @@ def _representative_lines(bom_no, keys):
|
||||
):
|
||||
representative.setdefault(tuple(line.get(key) for key in keys), line)
|
||||
|
||||
cache[bom_no] = representative
|
||||
return representative
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user