From 4406116f8666abae6416ac5371043752173ee35d Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Fri, 31 Jan 2025 20:24:28 +0530 Subject: [PATCH] feat: estimate table size --- frappe/database/database.py | 4 ++++ frappe/database/mariadb/database.py | 9 +++++++++ frappe/database/postgres/database.py | 8 ++++++++ frappe/tests/test_db.py | 3 +++ 4 files changed, 24 insertions(+) diff --git a/frappe/database/database.py b/frappe/database/database.py index 04895e5b01..84f9c74790 100644 --- a/frappe/database/database.py +++ b/frappe/database/database.py @@ -1250,6 +1250,10 @@ class Database: frappe.cache.set_value(f"doctype:count:{dt}", count, expires_in_sec=86400) return count + def estimate_count(self, doctype: str) -> int: + """Get estimated count of total rows in a table.""" + raise NotImplementedError + @staticmethod def format_date(date): return getdate(date).strftime("%Y-%m-%d") diff --git a/frappe/database/mariadb/database.py b/frappe/database/mariadb/database.py index 7aadb6be74..c96bcb3e0a 100644 --- a/frappe/database/mariadb/database.py +++ b/frappe/database/mariadb/database.py @@ -541,3 +541,12 @@ class MariaDBDatabase(MariaDBConnectionUtil, MariaDBExceptionUtil, Database): finally: self._cursor = original_cursor new_cursor.close() + + def estimate_count(self, doctype: str): + """Get estimated count of total rows in a table.""" + from frappe.utils.data import cint + + table = get_table_name(doctype) + + count = self.sql("select table_rows from information_schema.tables where table_name = %s", table) + return cint(count[0][0]) if count else 0 diff --git a/frappe/database/postgres/database.py b/frappe/database/postgres/database.py index c45c3ab666..b39cd86b40 100644 --- a/frappe/database/postgres/database.py +++ b/frappe/database/postgres/database.py @@ -483,6 +483,14 @@ class PostgresDatabase(PostgresExceptionUtil, Database): def get_database_list(self): return self.sql("SELECT datname FROM pg_database", pluck=True) + def estimate_count(self, doctype: str): + """Get estimated count of total rows in a table.""" + from frappe.utils.data import cint + + table = get_table_name(doctype) + count = self.sql("select reltuples from pg_class where relname = %s", table) + return cint(count[0][0]) if count else 0 + def modify_query(query): """ "Modifies query according to the requirements of postgres""" diff --git a/frappe/tests/test_db.py b/frappe/tests/test_db.py index 9452345c8b..0401fae25f 100644 --- a/frappe/tests/test_db.py +++ b/frappe/tests/test_db.py @@ -510,6 +510,9 @@ class TestDB(IntegrationTestCase): self.assertEqual(frappe.db.exists(dt, [["name", "=", dn]]), dn) + def test_estimated_count(self): + self.assertGreater(frappe.db.estimate_count("DocField"), 100) + def test_datetime_serialization(self): dt = now_datetime() dt = dt.replace(microsecond=0)