Merge pull request #22114 from gavindsouza/doc-bulk_insert-include_child
fix: Handle child record insertions via bulk_insert
This commit is contained in:
commit
fdcfb82f47
2 changed files with 50 additions and 13 deletions
|
|
@ -1643,12 +1643,32 @@ def bulk_insert(
|
|||
- Documents can be any iterable / generator containing Document objects
|
||||
"""
|
||||
|
||||
columns = frappe.get_meta(doctype).get_valid_columns()
|
||||
values = _document_values_generator(documents, columns)
|
||||
doctype_meta = frappe.get_meta(doctype)
|
||||
documents = list(documents)
|
||||
|
||||
frappe.db.bulk_insert(
|
||||
doctype, columns, values, ignore_duplicates=ignore_duplicates, chunk_size=chunk_size
|
||||
)
|
||||
valid_column_map = {
|
||||
doctype: doctype_meta.get_valid_columns(),
|
||||
}
|
||||
values_map = {
|
||||
doctype: _document_values_generator(documents, valid_column_map[doctype]),
|
||||
}
|
||||
|
||||
for child_table in doctype_meta.get_table_fields():
|
||||
valid_column_map[child_table.options] = frappe.get_meta(child_table.options).get_valid_columns()
|
||||
values_map[child_table.options] = _document_values_generator(
|
||||
(
|
||||
ch_doc
|
||||
for ch_doc in (
|
||||
child_docs for doc in documents for child_docs in doc.get(child_table.fieldname)
|
||||
)
|
||||
),
|
||||
valid_column_map[child_table.options],
|
||||
)
|
||||
|
||||
for dt, docs in values_map.items():
|
||||
frappe.db.bulk_insert(
|
||||
dt, valid_column_map[dt], docs, ignore_duplicates=ignore_duplicates, chunk_size=chunk_size
|
||||
)
|
||||
|
||||
|
||||
def _document_values_generator(
|
||||
|
|
|
|||
|
|
@ -521,17 +521,34 @@ class TestDocumentWebView(FrappeTestCase):
|
|||
def test_bulk_inserts(self):
|
||||
from frappe.model.document import bulk_insert
|
||||
|
||||
doctype = "ToDo"
|
||||
sent_todo = set()
|
||||
doctype = "Role Profile"
|
||||
child_field = "roles"
|
||||
child_doctype = frappe.get_meta(doctype).get_field(child_field).options
|
||||
|
||||
sent_docs = set()
|
||||
sent_child_docs = set()
|
||||
|
||||
def doc_generator():
|
||||
for i in range(690):
|
||||
for _ in range(21):
|
||||
doc = frappe.new_doc(doctype)
|
||||
doc.name = doc.description = frappe.generate_hash()
|
||||
sent_todo.add(doc.name)
|
||||
doc.role_profile = frappe.generate_hash()
|
||||
doc.append("roles", {"role": "System Manager"})
|
||||
|
||||
doc.set_new_name()
|
||||
doc.set_parent_in_children()
|
||||
|
||||
sent_docs.add(doc.name)
|
||||
sent_child_docs.add(doc.roles[0].name)
|
||||
|
||||
yield doc
|
||||
|
||||
bulk_insert(doctype, doc_generator(), chunk_size=100)
|
||||
bulk_insert(doctype, doc_generator(), chunk_size=5)
|
||||
|
||||
all_todos = set(frappe.get_all("ToDo", pluck="name"))
|
||||
self.assertEqual(sent_todo - all_todos, set(), "All docs should be inserted")
|
||||
all_docs = set(frappe.get_all(doctype, pluck="name"))
|
||||
all_child_docs = set(
|
||||
frappe.get_all(
|
||||
child_doctype, filters={"parenttype": doctype, "parentfield": child_field}, pluck="name"
|
||||
)
|
||||
)
|
||||
self.assertEqual(sent_docs - all_docs, set(), "All docs should be inserted")
|
||||
self.assertEqual(sent_child_docs - all_child_docs, set(), "All child docs should be inserted")
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue