diff --git a/frappe/__init__.py b/frappe/__init__.py index 379f242e32..c215023dd6 100644 --- a/frappe/__init__.py +++ b/frappe/__init__.py @@ -269,6 +269,10 @@ def init(site: str, sites_path: str = ".", new_site: bool = False, force=False) local.initialised = True + # Set the user as database name if not set in config + if local.conf and local.conf.db_name is not None and local.conf.db_user is None: + local.conf.db_user = local.conf.db_name + def connect( site: str | None = None, db_name: str | None = None, set_admin_as_user: bool = True @@ -287,7 +291,7 @@ def connect( local.db = get_db( host=local.conf.db_host, port=local.conf.db_port, - user=db_name or local.conf.db_name, + user=local.conf.db_user, password=None, ) if set_admin_as_user: diff --git a/frappe/commands/site.py b/frappe/commands/site.py index f016724f87..36bb71d7a1 100644 --- a/frappe/commands/site.py +++ b/frappe/commands/site.py @@ -68,6 +68,7 @@ def new_site( db_type=None, db_host=None, db_port=None, + db_user=None, set_default=False, setup_db=True, ): @@ -91,6 +92,7 @@ def new_site( db_type=db_type, db_host=db_host, db_port=db_port, + db_user=db_user, setup_db=setup_db, ) @@ -1058,7 +1060,9 @@ def _drop_site( sys.exit(1) click.secho("Dropping site database and user", fg="green") - drop_user_and_database(frappe.conf.db_name, db_root_username, db_root_password) + drop_user_and_database( + frappe.conf.db_name, frappe.conf.db_user, db_root_username, db_root_password + ) archived_sites_path = archived_sites_path or os.path.join( frappe.utils.get_bench_path(), "archived", "sites" diff --git a/frappe/database/__init__.py b/frappe/database/__init__.py index d88536ad99..7d9abc5eb4 100644 --- a/frappe/database/__init__.py +++ b/frappe/database/__init__.py @@ -36,20 +36,20 @@ def bootstrap_database(db_name, verbose=None, source_sql=None): return frappe.database.mariadb.setup_db.bootstrap_database(db_name, verbose, source_sql) -def drop_user_and_database(db_name, root_login=None, root_password=None): +def drop_user_and_database(db_name, db_user, root_login=None, root_password=None): import frappe if frappe.conf.db_type == "postgres": import frappe.database.postgres.setup_db return frappe.database.postgres.setup_db.drop_user_and_database( - db_name, root_login, root_password + db_name, db_user, root_login, root_password ) else: import frappe.database.mariadb.setup_db return frappe.database.mariadb.setup_db.drop_user_and_database( - db_name, root_login, root_password + db_name, db_user, root_login, root_password ) diff --git a/frappe/database/database.py b/frappe/database/database.py index b117c2c6dc..3f2c614b26 100644 --- a/frappe/database/database.py +++ b/frappe/database/database.py @@ -40,7 +40,6 @@ if TYPE_CHECKING: from pymysql.connections import Connection as MariadbConnection from pymysql.cursors import Cursor as MariadbCursor - IFNULL_PATTERN = re.compile(r"ifnull\(", flags=re.IGNORECASE) INDEX_PATTERN = re.compile(r"\s*\([^)]+\)\s*") SINGLE_WORD_PATTERN = re.compile(r'([`"]?)(tab([A-Z]\w+))\1') @@ -81,7 +80,7 @@ class Database: self.setup_type_map() self.host = host or frappe.conf.db_host self.port = port or frappe.conf.db_port - self.user = user or frappe.conf.db_name + self.user = user or frappe.conf.db_user self.cur_db_name = frappe.conf.db_name self._conn = None @@ -104,8 +103,8 @@ class Database: self.before_rollback = CallbackManager() self.after_rollback = CallbackManager() - # self.db_type: str - # self.last_query (lazy) attribute of last sql query executed + # self.db_type: str + # self.last_query (lazy) attribute of last sql query executed def setup_type_map(self): pass @@ -264,7 +263,8 @@ class Database: if not ( ignore_ddl - and (self.is_missing_column(e) or self.is_table_missing(e) or self.cant_drop_field_or_key(e)) + and (self.is_missing_column(e) or self.is_table_missing( + e) or self.cant_drop_field_or_key(e)) ): raise @@ -377,9 +377,11 @@ class Database: return self._cursor.mogrify(query, values) except AttributeError: if isinstance(values, dict): - return query % {k: frappe.db.escape(v) if isinstance(v, str) else v for k, v in values.items()} + return query % {k: frappe.db.escape(v) if isinstance(v, str) else v for k, v in + values.items()} elif isinstance(values, (list, tuple)): - return query % tuple(frappe.db.escape(v) if isinstance(v, str) else v for v in values) + return query % tuple( + frappe.db.escape(v) if isinstance(v, str) else v for v in values) return query, values def lazy_mogrify(self, query: Query, values: QueryValues) -> LazyMogrify: @@ -580,7 +582,8 @@ class Database: user = frappe.db.get_values("User", "test@example.com", "*")[0] """ out = None - if cache and isinstance(filters, str) and (doctype, filters, fieldname) in self.value_cache: + if cache and isinstance(filters, str) and ( + doctype, filters, fieldname) in self.value_cache: return self.value_cache[(doctype, filters, fieldname)] if distinct: @@ -628,20 +631,23 @@ class Database: skip_locked=skip_locked, ) except Exception as e: - if ignore and (frappe.db.is_missing_column(e) or frappe.db.is_table_missing(e)): + if ignore and ( + frappe.db.is_missing_column(e) or frappe.db.is_table_missing(e)): # table or column not found, return None out = None elif (not ignore) and frappe.db.is_table_missing(e): # table not found, look in singles out = self.get_values_from_single( - fields, filters, doctype, as_dict, debug, update, run=run, distinct=distinct + fields, filters, doctype, as_dict, debug, update, run=run, + distinct=distinct ) else: raise else: out = self.get_values_from_single( - fields, filters, doctype, as_dict, debug, update, run=run, pluck=pluck, distinct=distinct + fields, filters, doctype, as_dict, debug, update, run=run, pluck=pluck, + distinct=distinct ) if cache and isinstance(filters, str): @@ -752,7 +758,8 @@ class Database: @staticmethod def _get_update_dict( - fieldname: str | dict, value: Any, *, modified: str, modified_by: str, update_modified: bool + fieldname: str | dict, value: Any, *, modified: str, modified_by: str, + update_modified: bool ) -> dict[str, Any]: """Create update dict that represents column-values to be updated.""" update_dict = fieldname if isinstance(fieldname, dict) else {fieldname: value} @@ -788,7 +795,8 @@ class Database: """ to_update = self._get_update_dict( - fieldname, value, modified=modified, modified_by=modified_by, update_modified=update_modified + fieldname, value, modified=modified, modified_by=modified_by, + update_modified=update_modified ) frappe.db.delete( diff --git a/frappe/database/mariadb/setup_db.py b/frappe/database/mariadb/setup_db.py index de1173e507..9760ec1e66 100644 --- a/frappe/database/mariadb/setup_db.py +++ b/frappe/database/mariadb/setup_db.py @@ -26,6 +26,7 @@ def get_mariadb_version(version_string: str = ""): def setup_database(force, verbose, no_mariadb_socket=False): frappe.local.session = frappe._dict({"user": "Administrator"}) + db_user = frappe.conf.db_user db_name = frappe.local.conf.db_name root_conn = get_root_connection(frappe.flags.root_login, frappe.flags.root_password) dbman = DbManager(root_conn) @@ -34,34 +35,34 @@ def setup_database(force, verbose, no_mariadb_socket=False): dbman_kwargs["host"] = "%" if force or (db_name not in dbman.get_database_list()): - dbman.delete_user(db_name, **dbman_kwargs) + dbman.delete_user(db_user, **dbman_kwargs) dbman.drop_database(db_name) else: raise Exception(f"Database {db_name} already exists") - dbman.create_user(db_name, frappe.conf.db_password, **dbman_kwargs) + dbman.create_user(db_user, frappe.conf.db_password, **dbman_kwargs) if verbose: - print("Created user %s" % db_name) + print("Created user %s" % db_user) dbman.create_database(db_name) if verbose: print("Created database %s" % db_name) - dbman.grant_all_privileges(db_name, db_name, **dbman_kwargs) + dbman.grant_all_privileges(db_name, db_user, **dbman_kwargs) dbman.flush_privileges() if verbose: - print(f"Granted privileges to user {db_name} and database {db_name}") + print(f"Granted privileges to user {db_user} and database {db_name}") # close root connection root_conn.close() -def drop_user_and_database(db_name, root_login, root_password): +def drop_user_and_database(db_name, db_user, root_login, root_password): frappe.local.db = get_root_connection(root_login, root_password) dbman = DbManager(frappe.local.db) dbman.drop_database(db_name) - dbman.delete_user(db_name, host="%") - dbman.delete_user(db_name) + dbman.delete_user(db_user, host="%") + dbman.delete_user(db_user) def bootstrap_database(db_name, verbose, source_sql=None): diff --git a/frappe/database/postgres/setup_db.py b/frappe/database/postgres/setup_db.py index 5118a38509..264de90c95 100644 --- a/frappe/database/postgres/setup_db.py +++ b/frappe/database/postgres/setup_db.py @@ -81,7 +81,7 @@ def get_root_connection(root_login=None, root_password=None): return frappe.local.flags.root_connection -def drop_user_and_database(db_name, root_login, root_password): +def drop_user_and_database(db_name, db_user, root_login, root_password): root_conn = get_root_connection( frappe.flags.root_login or root_login, frappe.flags.root_password or root_password ) @@ -92,4 +92,4 @@ def drop_user_and_database(db_name, root_login, root_password): ) root_conn.sql("end") root_conn.sql(f"DROP DATABASE IF EXISTS {db_name}") - root_conn.sql(f"DROP USER IF EXISTS {db_name}") + root_conn.sql(f"DROP USER IF EXISTS {db_user}") diff --git a/frappe/installer.py b/frappe/installer.py index 1215aa8e0e..7dc6143799 100644 --- a/frappe/installer.py +++ b/frappe/installer.py @@ -49,6 +49,7 @@ def _new_site( db_type=None, db_host=None, db_port=None, + db_user=None, setup_db=True, ): """Install a new Frappe site""" @@ -97,6 +98,7 @@ def _new_site( db_type=db_type, db_host=db_host, db_port=db_port, + db_user=db_user, no_mariadb_socket=no_mariadb_socket, setup=setup_db, ) @@ -135,6 +137,7 @@ def install_db( db_type=None, db_host=None, db_port=None, + db_user=None, no_mariadb_socket=False, setup=True, ): @@ -156,6 +159,7 @@ def install_db( db_type=db_type, db_host=db_host, db_port=db_port, + db_user=db_user, ) frappe.flags.in_install_db = True @@ -533,11 +537,23 @@ def init_singles(): def make_conf( - db_name=None, db_password=None, site_config=None, db_type=None, db_host=None, db_port=None + db_name=None, + db_password=None, + site_config=None, + db_type=None, + db_host=None, + db_port=None, + db_user=None, ): site = frappe.local.site make_site_config( - db_name, db_password, site_config, db_type=db_type, db_host=db_host, db_port=db_port + db_name, + db_password, + site_config, + db_type=db_type, + db_host=db_host, + db_port=db_port, + db_user=db_user, ) sites_path = frappe.local.sites_path frappe.destroy() @@ -545,7 +561,13 @@ def make_conf( def make_site_config( - db_name=None, db_password=None, site_config=None, db_type=None, db_host=None, db_port=None + db_name=None, + db_password=None, + site_config=None, + db_type=None, + db_host=None, + db_port=None, + db_user=None, ): frappe.create_folder(os.path.join(frappe.local.site_path)) site_file = get_site_config_path() @@ -563,6 +585,9 @@ def make_site_config( if db_port: site_config["db_port"] = db_port + if db_user: + site_config["db_user"] = db_user + with open(site_file, "w") as f: f.write(json.dumps(site_config, indent=1, sort_keys=True)) diff --git a/frappe/integrations/offsite_backup_utils.py b/frappe/integrations/offsite_backup_utils.py index 0a5cd80ea6..e2e2fed40f 100644 --- a/frappe/integrations/offsite_backup_utils.py +++ b/frappe/integrations/offsite_backup_utils.py @@ -52,7 +52,7 @@ def get_latest_backup_file(with_files=False): odb = BackupGenerator( frappe.conf.db_name, - frappe.conf.db_name, + frappe.conf.db_user, frappe.conf.db_password, db_host=frappe.conf.db_host, db_port=frappe.conf.db_port, @@ -110,7 +110,7 @@ def generate_files_backup(): backup = BackupGenerator( frappe.conf.db_name, - frappe.conf.db_name, + frappe.conf.db_user, frappe.conf.db_password, db_host=frappe.conf.db_host, db_port=frappe.conf.db_port, diff --git a/frappe/utils/backups.py b/frappe/utils/backups.py index 0f9f26c75f..8276dcfe80 100644 --- a/frappe/utils/backups.py +++ b/frappe/utils/backups.py @@ -496,7 +496,7 @@ def fetch_latest_backups(partial=False) -> dict: frappe.only_for("System Manager") odb = BackupGenerator( frappe.conf.db_name, - frappe.conf.db_name, + frappe.conf.db_user, frappe.conf.db_password, db_host=frappe.conf.db_host, db_port=frappe.conf.db_port, @@ -563,7 +563,7 @@ def new_backup( delete_temp_backups() odb = BackupGenerator( frappe.conf.db_name, - frappe.conf.db_name, + frappe.conf.db_user or frappe.conf.db_name, frappe.conf.db_password, db_host=frappe.conf.db_host, db_port=frappe.conf.db_port,