seitime-frappe/frappe/database/mariadb/setup_db.py
Ankush Menat 7b8eb5d1b6
feat: MariaDB 11.8 support (#32289)
* ci: Switch to MariaDB 11.8

* ci: Use mariadb's latest client libraries

Co-Authored-By: Sagar Vora <sagar@resilient.tech>

---------

Co-authored-by: Sagar Vora <sagar@resilient.tech>
2025-06-12 10:11:24 +00:00

152 lines
4.2 KiB
Python

import os
import sys
import click
import frappe
from frappe.database.db_manager import DbManager
def get_mariadb_variables():
return frappe._dict(frappe.db.sql("show variables"))
def get_mariadb_version(version_string: str = ""):
# MariaDB classifies their versions as Major (1st and 2nd number), and Minor (3rd number)
# Example: Version 10.3.13 is Major Version = 10.3, Minor Version = 13
version_string = version_string or get_mariadb_variables().get("version")
version = version_string.split("-", 1)[0]
return version.rsplit(".", 1)
def setup_database(force, verbose, mariadb_user_host_login_scope=None):
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()
dbman = DbManager(root_conn)
dbman_kwargs = {}
if mariadb_user_host_login_scope is not None:
dbman_kwargs["host"] = mariadb_user_host_login_scope
dbman.create_user(db_user, frappe.conf.db_password, **dbman_kwargs)
if verbose:
print(f"Created or updated user {db_user}")
if force or (db_name not in dbman.get_database_list()):
dbman.drop_database(db_name)
else:
print(f"Database {db_name} already exists, please drop it manually or pass `--force`.")
sys.exit(1)
dbman.create_database(db_name)
if verbose:
print("Created database {}".format(db_name))
dbman.grant_all_privileges(db_name, db_user, **dbman_kwargs)
dbman.flush_privileges()
if verbose:
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,
db_user,
):
frappe.local.db = get_root_connection()
dbman = DbManager(frappe.local.db)
dbman.drop_database(db_name)
dbman.delete_user(db_user, host="%")
dbman.delete_user(db_user)
def bootstrap_database(verbose, source_sql=None):
import sys
frappe.connect()
check_compatible_versions()
import_db_from_sql(source_sql, verbose)
frappe.connect()
if "tabDefaultValue" not in frappe.db.get_tables(cached=False):
from click import secho
secho(
"Table 'tabDefaultValue' missing in the restored site. "
"This happens when the backup fails to restore. Please check that the file is valid\n"
"Do go through the above output to check the exact error message from MariaDB",
fg="red",
)
sys.exit(1)
def import_db_from_sql(source_sql=None, verbose=False):
if verbose:
print("Starting database import...")
db_name = frappe.conf.db_name
if not source_sql:
source_sql = os.path.join(os.path.dirname(__file__), "framework_mariadb.sql")
DbManager(frappe.local.db).restore_database(
verbose, db_name, source_sql, frappe.conf.db_user, frappe.conf.db_password
)
if verbose:
print("Imported from database {}".format(source_sql))
def check_compatible_versions():
try:
version = get_mariadb_version()
version_tuple = tuple(int(v) for v in version[0].split("."))
if version_tuple < (10, 6):
click.secho(
f"Warning: MariaDB version {version} is older than 10.6 which is not supported by Frappe",
fg="yellow",
)
elif version_tuple > (11, 8):
click.secho(
f"Warning: MariaDB version {version} is newer than 11.8 which is not yet tested with Frappe Framework.",
fg="yellow",
)
except Exception:
click.secho(
"MariaDB version compatibility checks failed, make sure you're running a supported version.",
fg="yellow",
)
def get_root_connection():
if not frappe.local.flags.root_connection:
from getpass import getpass
if not frappe.flags.root_login:
frappe.flags.root_login = (
frappe.conf.get("mariadb_root_login")
or frappe.conf.get("root_login")
or (sys.__stdin__.isatty() and input("Enter mysql super user [root]: "))
or "root"
)
if not frappe.flags.root_password:
frappe.flags.root_password = (
frappe.conf.get("mariadb_root_password")
or frappe.conf.get("root_password")
or getpass("MySQL root password: ")
)
frappe.local.flags.root_connection = frappe.database.get_db(
socket=frappe.conf.db_socket,
host=frappe.conf.db_host,
port=frappe.conf.db_port,
user=frappe.flags.root_login,
password=frappe.flags.root_password,
cur_db_name=None,
)
return frappe.local.flags.root_connection