fix: clear cache and prevent data access after DocType deletion (#34307)
* fix: clear cache and prevent data access after DocType deletion * fix: Handle potential DB failures during migrate --------- Co-authored-by: Ankush Menat <ankush@frappe.io>
This commit is contained in:
parent
598ba6d63d
commit
4ecb9bc57d
4 changed files with 35 additions and 12 deletions
|
|
@ -147,17 +147,26 @@ def _clear_doctype_cache_from_redis(doctype: str | None = None):
|
|||
clear_single(doctype)
|
||||
|
||||
# clear all parent doctypes
|
||||
for dt in frappe.get_all(
|
||||
"DocField", "parent", dict(fieldtype=["in", frappe.model.table_fields], options=doctype)
|
||||
):
|
||||
clear_single(dt.parent)
|
||||
|
||||
# clear all parent doctypes
|
||||
if not frappe.flags.in_install:
|
||||
try:
|
||||
for dt in frappe.get_all(
|
||||
"Custom Field", "dt", dict(fieldtype=["in", frappe.model.table_fields], options=doctype)
|
||||
"DocField",
|
||||
"parent",
|
||||
dict(fieldtype=["in", frappe.model.table_fields], options=doctype),
|
||||
ignore_ddl=True,
|
||||
):
|
||||
clear_single(dt.dt)
|
||||
clear_single(dt.parent)
|
||||
|
||||
# clear all parent doctypes
|
||||
if not frappe.flags.in_install:
|
||||
for dt in frappe.get_all(
|
||||
"Custom Field",
|
||||
"dt",
|
||||
dict(fieldtype=["in", frappe.model.table_fields], options=doctype),
|
||||
ignore_ddl=True,
|
||||
):
|
||||
clear_single(dt.dt)
|
||||
except frappe.DoesNotExistError:
|
||||
pass # core doctypes getting migrated.
|
||||
|
||||
# clear all notifications
|
||||
delete_notification_count_for(doctype)
|
||||
|
|
|
|||
|
|
@ -856,6 +856,16 @@ class TestDocType(IntegrationTestCase):
|
|||
)
|
||||
self.assertRaises(frappe.ValidationError, doctype.insert)
|
||||
|
||||
def test_delete_doc_clears_cache(self):
|
||||
dt = new_doctype(
|
||||
fields=[{"fieldname": "test_fdname", "fieldtype": "Data", "label": "Test Field"}],
|
||||
).insert()
|
||||
frappe.get_meta(dt.name)
|
||||
frappe.delete_doc("DocType", dt.name, force=1, delete_permanently=False)
|
||||
frappe.db.commit()
|
||||
with self.assertRaises(frappe.DoesNotExistError):
|
||||
frappe.get_meta(dt.name)
|
||||
|
||||
|
||||
def new_doctype(
|
||||
name: str | None = None,
|
||||
|
|
|
|||
|
|
@ -144,6 +144,8 @@ def delete_doc(
|
|||
# in case a doctype doesnt have any controller code nor any app and module
|
||||
pass
|
||||
|
||||
frappe.clear_cache(doctype=name)
|
||||
|
||||
else:
|
||||
# Lock the doc without waiting
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ class TestFixtureImport(IntegrationTestCase):
|
|||
self.assertFalse(frappe.db.exists("DocType", "temp_doctype"))
|
||||
|
||||
self.create_new_doctype("temp_doctype")
|
||||
frappe.db.commit()
|
||||
|
||||
dummy_name_list = ["jhon", "jane"]
|
||||
path_to_exported_fixtures = self.insert_dummy_data_and_export("temp_doctype", dummy_name_list)
|
||||
|
|
@ -39,9 +40,6 @@ class TestFixtureImport(IntegrationTestCase):
|
|||
|
||||
import_doc(path_to_exported_fixtures)
|
||||
|
||||
delete_doc("DocType", "temp_doctype", delete_permanently=True)
|
||||
os.remove(path_to_exported_fixtures)
|
||||
|
||||
self.assertEqual(frappe.db.count("temp_doctype"), len(dummy_name_list))
|
||||
|
||||
data = frappe.get_all("temp_doctype", "member_name")
|
||||
|
|
@ -53,6 +51,10 @@ class TestFixtureImport(IntegrationTestCase):
|
|||
|
||||
self.assertEqual(set(dummy_name_list), imported_data)
|
||||
|
||||
delete_doc("DocType", "temp_doctype", delete_permanently=True)
|
||||
frappe.db.commit()
|
||||
os.remove(path_to_exported_fixtures)
|
||||
|
||||
def test_singles_fixtures_import(self):
|
||||
self.assertFalse(frappe.db.exists("DocType", "temp_singles"))
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue