SqlLoaderWriter.__enter__()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 2
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 2
nop 1
dl 0
loc 2
ccs 0
cts 0
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
import abc
2
from typing import Any, Optional
3
4
from etlt.writer.Writer import Writer
5
6
7
class SqlLoaderWriter(Writer):
8
    """
9
    Abstract parent class for loading rows to a table in a database using a SQL statement for loading data from file.
10
    """
11
    handlers = {}
12
    """
13
    The handlers for writing objects as a field to a CSV file.
14
15
    :type: dict[str,callable]
16
    """
17
18
    # ------------------------------------------------------------------------------------------------------------------
19
    def __init__(self, filename: str, encoding: str = 'utf8'):
20
        """
21
        Object constructor.
22
23
        :param filename: The destination file for the rows.
24
        :param encoding: The encoding of the text of the destination file.
25
        """
26
        Writer.__init__(self)
27
28
        self._filename: str = filename
29
        """
30
        The name of the destination file.
31
        """
32
33
        self._encoding: str = encoding
34
        """
35
        The encoding of the text in the destination file.
36
        """
37
38
        self._file: Any = None
39
        """
40
        The underling file object.
41
        """
42
43
    # ------------------------------------------------------------------------------------------------------------------
44
    def __enter__(self):
45
        self._file = open(self._filename, mode='wt', encoding=self._encoding)
46
47
    # ------------------------------------------------------------------------------------------------------------------
48
    def __exit__(self, exc_type, exc_value, traceback):
49
        self._file.close()
50
51
    # ------------------------------------------------------------------------------------------------------------------
52
    @property
53
    def filename(self) -> str:
54
        """
55
        Returns the filename.
56
        """
57
        return self._filename
58
59
    # ------------------------------------------------------------------------------------------------------------------
60
    @property
61
    def encoding(self) -> str:
62
        """
63
        Returns the encoding.
64
        """
65
        return self._encoding
66
67
    # ------------------------------------------------------------------------------------------------------------------
68
    @abc.abstractmethod
69
    def get_bulk_load_sql(self, table_name: str, partition: Optional[str] = None) -> str:
70
        """
71
        Returns a SQL statement for bulk loading the data writen to the destination file into a table.
72
73
        :param table_name: The name of the table.
74
        :param partition: When applicable, the name of the partition in which the data must be loaded.`
75
        """
76
        raise NotImplementedError()
77
78
    # ------------------------------------------------------------------------------------------------------------------
79
    @staticmethod
80
    def register_handler(class_name: str, handler: callable) -> None:
81
        """
82
        Registers a handler for writing instances of a class as a field to the destination file.
83
84
        :param class_name: The name of the class.
85
        :param handler: The handler. This handler will be called with two arguments: the object which value must be
86
                        writen to the destination file, the file handler.
87
        """
88
        SqlLoaderWriter.handlers[class_name] = handler
89
90
    # ------------------------------------------------------------------------------------------------------------------
91
    def _write_field(self, value: Any):
92
        """
93
        Writes a single field to the destination file.
94
95
        :param value: The value of the field.
96
        """
97
        class_name = str(value.__class__)
98
        if class_name not in self.handlers:
99
            raise ValueError('No handler has been registered for class: {0!s}'.format(class_name))
100
        handler = self.handlers[class_name]
101
        handler(value, self._file)
102
103
# ----------------------------------------------------------------------------------------------------------------------
104