Source code for django_snapshots.connectors.mysql

"""MySQLConnector — uses mysqldump and mysql.

Requires ``mysqldump`` and ``mysql`` binaries on PATH.
Works for both MySQL and MariaDB.
"""

from __future__ import annotations

import subprocess
from pathlib import Path
from typing import Any

from django.conf import settings as django_settings

from django_snapshots.exceptions import SnapshotConnectorError


[docs] class MySQLConnector: """Back up and restore MySQL/MariaDB databases using ``mysqldump`` and ``mysql``.""" def _db_config(self, db_alias: str) -> dict[str, Any]: return django_settings.DATABASES[db_alias] def _base_args(self, config: dict[str, Any]) -> list[str]: args: list[str] = [] if config.get("HOST"): args += ["-h", config["HOST"]] if config.get("PORT"): args += ["-P", str(config["PORT"])] if config.get("USER"): args += ["-u", config["USER"]] if config.get("PASSWORD"): args += [f"-p{config['PASSWORD']}"] return args
[docs] def dump(self, db_alias: str, dest: Path) -> dict[str, Any]: """Dump the MySQL/MariaDB database to *dest* using ``mysqldump``.""" config = self._db_config(db_alias) dest.parent.mkdir(parents=True, exist_ok=True) cmd = ( ["mysqldump"] + self._base_args(config) + [ "--column-statistics=0", # MariaDB lacks COLUMN_STATISTICS in info_schema "--set-gtid-purged=OFF", # avoid GTID_PURGED conflicts on restore config["NAME"], ] ) try: with open(dest, "wb") as out: subprocess.run(cmd, stdout=out, stderr=subprocess.PIPE, check=True) except subprocess.CalledProcessError as exc: raise SnapshotConnectorError( f"mysqldump failed for alias {db_alias!r}:\n" f"{exc.stderr.decode(errors='replace')}" ) from exc return {"format": "sql"}
[docs] def restore(self, db_alias: str, src: Path) -> None: """Restore the MySQL/MariaDB database from *src* using ``mysql``.""" config = self._db_config(db_alias) cmd = ["mysql"] + self._base_args(config) + [config["NAME"]] try: with open(src, "rb") as f: subprocess.run(cmd, stdin=f, check=True, capture_output=True) except subprocess.CalledProcessError as exc: raise SnapshotConnectorError( f"mysql restore failed for alias {db_alias!r}:\n" f"{exc.stderr.decode(errors='replace')}" ) from exc