Init
This commit is contained in:
98
app/db/backup_engine.py
Normal file
98
app/db/backup_engine.py
Normal file
@@ -0,0 +1,98 @@
|
||||
import time
|
||||
from abc import ABC, abstractmethod
|
||||
import gzip
|
||||
import subprocess
|
||||
import uuid
|
||||
from typing import Any
|
||||
|
||||
from .models import DB, DBBackup
|
||||
# https://medium.com/poka-techblog/5-different-ways-to-backup-your-postgresql-database-using-python-3f06cea4f51
|
||||
|
||||
|
||||
class BackupEngineBase(ABC):
|
||||
def __init__(self, backupdb: DBBackup):
|
||||
self.backup_instance = backupdb
|
||||
self.db_instance = self.backup_instance.db
|
||||
|
||||
# self.db_instance = db_instance
|
||||
# self.backup_instance = BackupDB.objects.create(
|
||||
# db=self.db_instance,
|
||||
# rel_path="{db_id}-{timestamp}-{rand_gen}.{db_type}.{ext}".format(
|
||||
# db_id=self.db_instance.id,
|
||||
# timestamp=int(time.time()),
|
||||
# rand_gen=uuid.uuid4().hex[:5],
|
||||
# db_type=self.db_instance.db_type,
|
||||
# ext='sql.gz' if self.gzip else 'sql'
|
||||
# ),
|
||||
# )
|
||||
self.credentials = {"database": self.db_instance.db_name, **self.db_instance.credential.credentials}
|
||||
|
||||
@property
|
||||
@abstractmethod
|
||||
def cmd_kwargs(self) -> dict[str, Any]:
|
||||
...
|
||||
|
||||
@property
|
||||
def format_cmd_kwargs(self):
|
||||
return " ".join([
|
||||
key if isinstance(value, bool) else f"{key} {value}"
|
||||
for key, value in self.cmd_kwargs.items()
|
||||
if value
|
||||
])
|
||||
|
||||
@property
|
||||
@abstractmethod
|
||||
def cmd(self):
|
||||
...
|
||||
|
||||
@property
|
||||
def cmd_format(self):
|
||||
return self.cmd.format(cmd_kwargs=self.format_cmd_kwargs, **self.credentials)
|
||||
|
||||
def popen(self):
|
||||
return subprocess.Popen(self.cmd_format,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
shell=True,
|
||||
universal_newlines=True)
|
||||
|
||||
def file_obj(self, path):
|
||||
return gzip.open(path, "wb")
|
||||
|
||||
def run(self, task_id=None):
|
||||
self.backup_instance.update_task_id(task_id)
|
||||
try:
|
||||
with self.file_obj(self.backup_instance.abs_path) as f:
|
||||
with self.popen() as proc:
|
||||
self.backup_instance.update_status("running")
|
||||
for line in iter(proc.stdout.readline, ""):
|
||||
f.write(line.encode())
|
||||
except Exception as e:
|
||||
self.backup_instance.update_status("finished")
|
||||
raise e
|
||||
|
||||
|
||||
class MySQLBackupEngine(BackupEngineBase):
|
||||
@property
|
||||
def cmd_kwargs(self) -> dict[str, Any]:
|
||||
return {
|
||||
"--no-tablespaces": True
|
||||
}
|
||||
|
||||
@property
|
||||
def cmd(self):
|
||||
return "mysqldump {cmd_kwargs} -h {host} -P {port} -u {user} -p{password} {database}"
|
||||
|
||||
|
||||
class PostgreSQLBackupEngine(BackupEngineBase):
|
||||
@property
|
||||
def cmd_kwargs(self) -> dict[str, Any]:
|
||||
return {
|
||||
"--no-owner": True,
|
||||
"--no-privileges": True,
|
||||
"--clean": False
|
||||
}
|
||||
|
||||
@property
|
||||
def cmd(self):
|
||||
return "pg_dump {cmd_kwargs} --dbname=postgresql://{user}:{password}@{host}:{port}/{database}"
|
||||
Reference in New Issue
Block a user