瀏覽代碼

Merge pull request #16474 from resilient-tech/perf-get-doc-filters

perf: reduce query when calling `get_doc` with filters
version-14
gavin 3 年之前
committed by GitHub
父節點
當前提交
3f6bbd6349
沒有發現已知的金鑰在資料庫的簽署中 GPG 金鑰 ID: 4AEE18F83AFDEB23
共有 2 個檔案被更改,包括 28 行新增33 行删除
  1. +7
    -4
      frappe/database/database.py
  2. +21
    -29
      frappe/model/document.py

+ 7
- 4
frappe/database/database.py 查看文件

@@ -550,7 +550,7 @@ class Database(object):
return r and [[i[1] for i in r]] or [] return r and [[i[1] for i in r]] or []




def get_singles_dict(self, doctype, debug = False):
def get_singles_dict(self, doctype, debug=False, *, for_update=False):
"""Get Single DocType as dict. """Get Single DocType as dict.


:param doctype: DocType of the single object whose value is requested :param doctype: DocType of the single object whose value is requested
@@ -561,10 +561,13 @@ class Database(object):
account_settings = frappe.db.get_singles_dict("Accounts Settings") account_settings = frappe.db.get_singles_dict("Accounts Settings")
""" """
result = self.query.get_sql( result = self.query.get_sql(
"Singles", filters={"doctype": doctype}, fields=["field", "value"]
"Singles",
filters={"doctype": doctype},
fields=["field", "value"],
for_update=for_update,
).run() ).run()
dict_ = frappe._dict(result)
return dict_
return frappe._dict(result)


@staticmethod @staticmethod
def get_all(*args, **kwargs): def get_all(*args, **kwargs):


+ 21
- 29
frappe/model/document.py 查看文件

@@ -88,35 +88,27 @@ class Document(BaseDocument):
If DocType name and document name are passed, the object will load If DocType name and document name are passed, the object will load
all values (including child documents) from the database. all values (including child documents) from the database.
""" """
self.doctype = self.name = None
self._default_new_docs = {}
self.doctype = None
self.name = None
self.flags = frappe._dict() self.flags = frappe._dict()


if args and args[0] and isinstance(args[0], str):
# first arugment is doctype
if len(args)==1:
# single
self.doctype = self.name = args[0]
else:
if args and args[0]:
if isinstance(args[0], str):
# first arugment is doctype
self.doctype = args[0] self.doctype = args[0]
if isinstance(args[1], dict):
# filter
self.name = frappe.db.get_value(args[0], args[1], "name")
if self.name is None:
frappe.throw(_("{0} {1} not found").format(_(args[0]), args[1]),
frappe.DoesNotExistError)
else:
self.name = args[1]


if 'for_update' in kwargs:
self.flags.for_update = kwargs.get('for_update')
# doctype for singles, string value or filters for other documents
self.name = self.doctype if len(args) == 1 else args[1]


self.load_from_db()
return
# for_update is set in flags to avoid changing load_from_db signature
# since it is used in virtual doctypes and inherited in child classes
self.flags.for_update = kwargs.get("for_update")
self.load_from_db()
return


if args and args[0] and isinstance(args[0], dict):
# first argument is a dict
kwargs = args[0]
if isinstance(args[0], dict):
# first argument is a dict
kwargs = args[0]


if kwargs: if kwargs:
# init base document # init base document
@@ -133,17 +125,15 @@ class Document(BaseDocument):
frappe.whitelist()(fn) frappe.whitelist()(fn)
return fn return fn


def reload(self):
"""Reload document from database"""
self.load_from_db()

def load_from_db(self): def load_from_db(self):
"""Load document and children from database and create properties """Load document and children from database and create properties
from fields""" from fields"""
if not getattr(self, "_metaclass", False) and self.meta.issingle: if not getattr(self, "_metaclass", False) and self.meta.issingle:
single_doc = frappe.db.get_singles_dict(self.doctype)
single_doc = frappe.db.get_singles_dict(
self.doctype, for_update=self.flags.for_update
)
if not single_doc: if not single_doc:
single_doc = frappe.new_doc(self.doctype).as_dict()
single_doc = frappe.new_doc(self.doctype, as_dict=True)
single_doc["name"] = self.doctype single_doc["name"] = self.doctype
del single_doc["__islocal"] del single_doc["__islocal"]


@@ -177,6 +167,8 @@ class Document(BaseDocument):
if hasattr(self, "__setup__"): if hasattr(self, "__setup__"):
self.__setup__() self.__setup__()


reload = load_from_db

def get_latest(self): def get_latest(self):
if not getattr(self, "latest", None): if not getattr(self, "latest", None):
self.latest = frappe.get_doc(self.doctype, self.name) self.latest = frappe.get_doc(self.doctype, self.name)


Loading…
取消
儲存