diff --git a/frappe/core/doctype/doctype/doctype.py b/frappe/core/doctype/doctype/doctype.py index acc5c4871d..f4760ec3c6 100644 --- a/frappe/core/doctype/doctype/doctype.py +++ b/frappe/core/doctype/doctype/doctype.py @@ -329,7 +329,7 @@ class DocType(Document): "DocField", "parent", dict(fieldtype=["in", frappe.model.table_fields], options=self.name) ) for p in parent_list: - frappe.db.update("DocType", p.parent, {}, for_update=False) + frappe.db.set_value("DocType", p.parent, {}, for_update=False) def scrub_field_names(self): """Sluggify fieldnames if not set from Label.""" diff --git a/frappe/core/doctype/user/user.py b/frappe/core/doctype/user/user.py index 092f7fa45d..3dc43ccc33 100644 --- a/frappe/core/doctype/user/user.py +++ b/frappe/core/doctype/user/user.py @@ -471,7 +471,7 @@ class User(Document): frappe.rename_doc("Notification Settings", old_name, new_name, force=True, show_alert=False) # set email - frappe.db.update("User", new_name, "email", new_name) + frappe.db.set_value("User", new_name, "email", new_name) def append_roles(self, *roles): """Add roles to user""" diff --git a/frappe/database/database.py b/frappe/database/database.py index 47ca451289..dfcc9dfe58 100644 --- a/frappe/database/database.py +++ b/frappe/database/database.py @@ -30,7 +30,7 @@ from frappe.model.utils.link_count import flush_local_link_count from frappe.query_builder.functions import Count from frappe.utils import cast as cast_fieldtype from frappe.utils import cint, get_datetime, get_table_name, getdate, now, sbool -from frappe.utils.deprecations import deprecated, deprecation_warning +from frappe.utils.deprecations import deprecated IFNULL_PATTERN = re.compile(r"ifnull\(", flags=re.IGNORECASE) INDEX_PATTERN = re.compile(r"\s*\([^)]+\)\s*") @@ -147,12 +147,11 @@ class Database: self, query: Query, values: QueryValues = EmptyQueryValues, + *, as_dict=0, as_list=0, - formatted=0, debug=0, ignore_ddl=0, - as_utf8=0, auto_commit=0, update=None, explain=False, @@ -165,10 +164,8 @@ class Database: :param values: Tuple / List / Dict of values to be escaped and substituted in the query. :param as_dict: Return as a dictionary. :param as_list: Always return as a list. - :param formatted: Format values like date etc. :param debug: Print query and `EXPLAIN` in debug log. :param ignore_ddl: Catch exception if table, column missing. - :param as_utf8: Encode values as UTF 8. :param auto_commit: Commit after executing the query. :param update: Update this dict to all rows (if returned `as_dict`). :param run: Returns query without executing it if False. @@ -274,20 +271,15 @@ class Database: if pluck: return [r[0] for r in self.last_result] - if as_utf8: - deprecation_warning("as_utf8 parameter is deprecated and will be removed in version 15.") - if formatted: - deprecation_warning("formatted parameter is deprecated and will be removed in version 15.") - # scrub output if required if as_dict: - ret = self.fetch_as_dict(formatted, as_utf8) + ret = self.fetch_as_dict() if update: for r in ret: r.update(update) return ret - elif as_list or as_utf8: - return self.convert_to_lists(self.last_result, formatted, as_utf8) + elif as_list: + return self.convert_to_lists(self.last_result) return self.last_result def _log_query(self, mogrified_query: str, debug: bool = False, explain: bool = False) -> None: @@ -394,62 +386,27 @@ class Database: ): raise ImplicitCommitError("This statement can cause implicit commit") - def fetch_as_dict(self, formatted=0, as_utf8=0) -> list[frappe._dict]: + def fetch_as_dict(self) -> list[frappe._dict]: """Internal. Converts results to dict.""" result = self.last_result if result: keys = [column[0] for column in self._cursor.description] - if not as_utf8: - return [frappe._dict(zip(keys, row)) for row in result] - - ret = [] - for r in result: - values = [] - for value in r: - if as_utf8 and isinstance(value, str): - value = value.encode("utf-8") - values.append(value) - - ret.append(frappe._dict(zip(keys, values))) - return ret + return [frappe._dict(zip(keys, row)) for row in result] @staticmethod def clear_db_table_cache(query): if query and is_query_type(query, ("drop", "create")): frappe.cache().delete_key("db_tables") - @staticmethod - def needs_formatting(result, formatted): - """Returns true if the first row in the result has a Date, Datetime, Long Int.""" - if result and result[0]: - for v in result[0]: - if isinstance(v, (datetime.date, datetime.timedelta, datetime.datetime, int)): - return True - if formatted and isinstance(v, (int, float)): - return True - - return False - def get_description(self): """Returns result metadata.""" return self._cursor.description @staticmethod - def convert_to_lists(res, formatted=0, as_utf8=0): + def convert_to_lists(res): """Convert tuple output to lists (internal).""" - if not as_utf8: - return [[value for value in row] for row in res] - - nres = [] - for r in res: - nr = [] - for val in r: - if as_utf8 and isinstance(val, str): - val = val.encode("utf-8") - nr.append(val) - nres.append(nr) - return nres + return [[value for value in row] for row in res] def get(self, doctype, filters=None, as_dict=True, cache=False): """Returns `get_value` with fieldname='*'""" @@ -849,11 +806,6 @@ class Database: ).run(debug=debug, run=run, as_dict=as_dict) return {} - @deprecated - def update(self, *args, **kwargs): - """Update multiple values. Alias for `set_value`.""" - return self.set_value(*args, **kwargs) - def set_value( self, dt, @@ -879,7 +831,6 @@ class Database: :param modified_by: Set this user as `modified_by`. :param update_modified: default True. Set as false, if you don't want to update the timestamp. :param debug: Print the query in the developer / js console. - :param for_update: [DEPRECATED] This function now performs updates in single query, locking is not required. """ is_single_doctype = not (dn and dt != dn) to_update = field if isinstance(field, dict) else {field: val} @@ -889,9 +840,6 @@ class Database: modified_by = modified_by or frappe.session.user to_update.update({"modified": modified, "modified_by": modified_by}) - if for_update: - deprecation_warning("for_update parameter is deprecated and will be removed in v15.") - if is_single_doctype: frappe.db.delete( "Singles", filters={"field": ("in", tuple(to_update)), "doctype": dt}, debug=debug @@ -922,32 +870,6 @@ class Database: if dt in self.value_cache: del self.value_cache[dt] - @staticmethod - @deprecated - def set(doc, field, val): - """Set value in document. **Avoid**""" - doc.db_set(field, val) - - @deprecated - def touch(self, doctype, docname): - """Update the modified timestamp of this document.""" - modified = now() - DocType = frappe.qb.DocType(doctype) - frappe.qb.update(DocType).set(DocType.modified, modified).where(DocType.name == docname).run() - return modified - - @staticmethod - def set_temp(value): - """Set a temperory value and return a key.""" - key = frappe.generate_hash() - frappe.cache().hset("temp", key, value) - return key - - @staticmethod - def get_temp(key): - """Return the temperory value and delete it.""" - return frappe.cache().hget("temp", key) - def set_global(self, key, val, user="__global"): """Save a global key value. Global values will be automatically set if they match fieldname.""" self.set_default(key, val, user) @@ -1107,7 +1029,7 @@ class Database: return getdate(date).strftime("%Y-%m-%d") @staticmethod - def format_datetime(datetime): + def format_datetime(datetime): # noqa: F811 if not datetime: return FallBackDateTimeStr @@ -1251,10 +1173,6 @@ class Database: """ return self.sql_ddl(f"truncate `{get_table_name(doctype)}`") - @deprecated - def clear_table(self, doctype): - return self.truncate(doctype) - def get_last_created(self, doctype): last_record = self.get_all(doctype, ("creation"), limit=1, order_by="creation desc") if last_record: diff --git a/frappe/email/doctype/newsletter/test_newsletter.py b/frappe/email/doctype/newsletter/test_newsletter.py index f80d218bca..a25b6bda02 100644 --- a/frappe/email/doctype/newsletter/test_newsletter.py +++ b/frappe/email/doctype/newsletter/test_newsletter.py @@ -74,7 +74,7 @@ class TestNewsletterMixin: ).insert(ignore_if_duplicate=True) except Exception: frappe.db.rollback(save_point=savepoint) - frappe.db.update(doctype, email_filters, "unsubscribed", 0) + frappe.db.set_value(doctype, email_filters, "unsubscribed", 0) frappe.db.release_savepoint(savepoint) diff --git a/frappe/patches/v13_0/queryreport_columns.py b/frappe/patches/v13_0/queryreport_columns.py index 3081823db6..e9176952d4 100644 --- a/frappe/patches/v13_0/queryreport_columns.py +++ b/frappe/patches/v13_0/queryreport_columns.py @@ -15,4 +15,4 @@ def execute(): if isinstance(data, list): # double escape braces jstr = f'{{"columns":{jstr}}}' - frappe.db.update("Report", record["name"], "json", jstr) + frappe.db.set_value("Report", record["name"], "json", jstr) diff --git a/frappe/patches/v14_0/remove_db_aggregation.py b/frappe/patches/v14_0/remove_db_aggregation.py index 4b0a58c2d6..cff2b583ce 100644 --- a/frappe/patches/v14_0/remove_db_aggregation.py +++ b/frappe/patches/v14_0/remove_db_aggregation.py @@ -32,4 +32,4 @@ def execute(): for agg in ["avg", "max", "min", "sum"]: script = re.sub(f"frappe.db.{agg}\\(", f"frappe.qb.{agg}(", script) - frappe.db.update("Server Script", name, "script", script) + frappe.db.set_value("Server Script", name, "script", script) diff --git a/frappe/tests/test_db.py b/frappe/tests/test_db.py index d8259975da..3962cc746d 100644 --- a/frappe/tests/test_db.py +++ b/frappe/tests/test_db.py @@ -791,23 +791,6 @@ class TestDBSetValue(FrappeTestCase): cached_doc = frappe.get_cached_doc(self.todo2.doctype, self.todo2.name) self.assertEqual(cached_doc.description, description) - def test_update_alias(self): - args = (self.todo1.doctype, self.todo1.name, "description", "Updated by `test_update_alias`") - kwargs = { - "for_update": False, - "modified": None, - "modified_by": None, - "update_modified": True, - "debug": False, - } - - self.assertTrue("return self.set_value(" in inspect.getsource(frappe.db.update)) - - with patch.object(Database, "set_value") as set_value: - frappe.db.update(*args, **kwargs) - set_value.assert_called_once() - set_value.assert_called_with(*args, **kwargs) - @classmethod def tearDownClass(cls): frappe.db.rollback()