Initial work on a full backup option
Creates the Backup command and a general serializer.
This commit is contained in:
parent
0a0bc1baa0
commit
a355ec3642
@ -51,6 +51,12 @@ class Operation(Enum):
|
|||||||
ImportCategoryGroups = auto()
|
ImportCategoryGroups = auto()
|
||||||
|
|
||||||
|
|
||||||
|
class ExportFormat(Enum):
|
||||||
|
CSV = auto()
|
||||||
|
JSON = auto()
|
||||||
|
pickle = auto()
|
||||||
|
|
||||||
|
|
||||||
class TransactionError(Exception):
|
class TransactionError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|||||||
40
pfbudget/core/command.py
Normal file
40
pfbudget/core/command.py
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
from abc import ABC, abstractmethod
|
||||||
|
import csv
|
||||||
|
import json
|
||||||
|
from pathlib import Path
|
||||||
|
import pickle
|
||||||
|
from typing import Any, Type
|
||||||
|
|
||||||
|
from pfbudget.common.types import ExportFormat
|
||||||
|
from pfbudget.db.client import Client
|
||||||
|
from pfbudget.utils.serializer import serialize
|
||||||
|
|
||||||
|
|
||||||
|
class Command(ABC):
|
||||||
|
@abstractmethod
|
||||||
|
def execute(self) -> None:
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def undo(self) -> None:
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
|
class ExportCommand(Command):
|
||||||
|
def __init__(self, client: Client, what: Type[Any], fn: Path, format: ExportFormat):
|
||||||
|
self.__client = client
|
||||||
|
self.what = what
|
||||||
|
self.fn = fn
|
||||||
|
self.format = format
|
||||||
|
|
||||||
|
def execute(self) -> None:
|
||||||
|
values = self.__client.select(self.what)
|
||||||
|
match self.format:
|
||||||
|
case ExportFormat.CSV:
|
||||||
|
with open(self.fn, "w", newline="") as f:
|
||||||
|
csv.writer(f).writerows([serialize(e) for e in values])
|
||||||
|
case ExportFormat.JSON:
|
||||||
|
with open(self.fn, "w", newline="") as f:
|
||||||
|
json.dump([serialize(e) for e in values], f, indent=4, default=str)
|
||||||
|
case ExportFormat.pickle:
|
||||||
|
with open(self.fn, "wb") as f:
|
||||||
|
pickle.dump([serialize(e) for e in values], f)
|
||||||
21
pfbudget/utils/serializer.py
Normal file
21
pfbudget/utils/serializer.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
from collections.abc import Mapping
|
||||||
|
from dataclasses import fields
|
||||||
|
from functools import singledispatch
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from pfbudget.db.model import Transaction, TransactionCategory
|
||||||
|
|
||||||
|
|
||||||
|
@singledispatch
|
||||||
|
def serialize(obj: Any) -> Mapping[str, Any]:
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
|
@serialize.register
|
||||||
|
def _(obj: Transaction) -> Mapping[str, Any]:
|
||||||
|
return dict((field.name, getattr(obj, field.name)) for field in fields(obj))
|
||||||
|
|
||||||
|
|
||||||
|
@serialize.register
|
||||||
|
def _(obj: TransactionCategory) -> Mapping[str, Any]:
|
||||||
|
return dict((field.name, getattr(obj, field.name)) for field in fields(obj))
|
||||||
Loading…
x
Reference in New Issue
Block a user