Skip to content

base

ColumnBase

Base class for all Column classes.

Mostly here to avoid circular dependencies with modules that need to know about the fields below.

Source code in src/embar/column/base.py
81
82
83
84
85
86
87
88
89
90
91
92
class ColumnBase:
    """
    Base class for all [`Column`][embar.column.common.Column] classes.

    Mostly here to avoid circular dependencies with modules that need to know about the fields below.
    """

    info: ColumnInfo  # pyright:ignore[reportUninitializedInstanceVariable]

    # These must always be assigned by children, type-checker won't catch it
    _sql_type: str  # pyright:ignore[reportUninitializedInstanceVariable]
    _py_type: Type  # pyright:ignore[reportUninitializedInstanceVariable]

ColumnInfo dataclass

ColumnInfo is the type that ultimately holds all the db column info.

It knows nothing about the python field: its name, what type it should deserialize to etc.

Source code in src/embar/column/base.py
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
@dataclass
class ColumnInfo:
    """
    `ColumnInfo` is the type that ultimately holds all the db column info.

    It knows nothing about the python field: its name, what type it should deserialize to etc.
    """

    # _table_name is callable as generally the `Table` won't yet have a name
    # at the time the Column is created.
    _table_name: Callable[[], str]

    name: str
    col_type: str
    py_type: Type
    primary: bool
    not_null: bool
    default: Any | None = None

    ref: ColumnInfo | None = None
    on_delete: OnDelete | None = None

    args: str | None = None

    @property
    def table_name(self) -> str:
        return self._table_name()

    def fqn(self) -> str:
        """
        Return the Fully Qualified Name (table and column both in quotes).

        ```python
        from embar.column.base import ColumnInfo
        col = ColumnInfo(
           _table_name=lambda: "foo", name="bar", col_type="TEXT", py_type=str, primary=False, not_null=False
        )
        fqn = col.fqn()
        assert fqn == '"foo"."bar"'
        ```
        """
        return f'"{self._table_name()}"."{self.name}"'

    def ddl(self) -> str:
        """
        Generate the DDL just for this column.

        Used by the [`Table.ddl()`][embar.table.Table.ddl] method to generate the full DDL.

        ```python
        from embar.column.base import ColumnInfo
        col = ColumnInfo(
           _table_name=lambda: "foo", name="bar", col_type="TEXT", py_type=str, primary=True, not_null=True
        )
        ddl = col.ddl()
        assert ddl == '"bar" TEXT NOT NULL PRIMARY KEY'
        ```
        """
        args = self.args if self.args is not None else ""
        default = f"DEFAULT '{self.default}'" if self.default is not None else ""
        nullable = "NOT NULL" if self.not_null else ""
        primary = "PRIMARY KEY" if self.primary else ""
        reference = f'REFERENCES "{self.ref.table_name}"("{self.ref.name}")' if self.ref is not None else ""
        on_delete = f"ON DELETE {self.on_delete}" if self.on_delete is not None else ""
        text = f'"{self.name}" {self.col_type}{args} {default} {nullable} {primary} {reference} {on_delete}'
        clean = " ".join(text.split()).strip()
        return clean

ddl()

Generate the DDL just for this column.

Used by the Table.ddl() method to generate the full DDL.

from embar.column.base import ColumnInfo
col = ColumnInfo(
   _table_name=lambda: "foo", name="bar", col_type="TEXT", py_type=str, primary=True, not_null=True
)
ddl = col.ddl()
assert ddl == '"bar" TEXT NOT NULL PRIMARY KEY'
Source code in src/embar/column/base.py
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
def ddl(self) -> str:
    """
    Generate the DDL just for this column.

    Used by the [`Table.ddl()`][embar.table.Table.ddl] method to generate the full DDL.

    ```python
    from embar.column.base import ColumnInfo
    col = ColumnInfo(
       _table_name=lambda: "foo", name="bar", col_type="TEXT", py_type=str, primary=True, not_null=True
    )
    ddl = col.ddl()
    assert ddl == '"bar" TEXT NOT NULL PRIMARY KEY'
    ```
    """
    args = self.args if self.args is not None else ""
    default = f"DEFAULT '{self.default}'" if self.default is not None else ""
    nullable = "NOT NULL" if self.not_null else ""
    primary = "PRIMARY KEY" if self.primary else ""
    reference = f'REFERENCES "{self.ref.table_name}"("{self.ref.name}")' if self.ref is not None else ""
    on_delete = f"ON DELETE {self.on_delete}" if self.on_delete is not None else ""
    text = f'"{self.name}" {self.col_type}{args} {default} {nullable} {primary} {reference} {on_delete}'
    clean = " ".join(text.split()).strip()
    return clean

fqn()

Return the Fully Qualified Name (table and column both in quotes).

from embar.column.base import ColumnInfo
col = ColumnInfo(
   _table_name=lambda: "foo", name="bar", col_type="TEXT", py_type=str, primary=False, not_null=False
)
fqn = col.fqn()
assert fqn == '"foo"."bar"'
Source code in src/embar/column/base.py
40
41
42
43
44
45
46
47
48
49
50
51
52
53
def fqn(self) -> str:
    """
    Return the Fully Qualified Name (table and column both in quotes).

    ```python
    from embar.column.base import ColumnInfo
    col = ColumnInfo(
       _table_name=lambda: "foo", name="bar", col_type="TEXT", py_type=str, primary=False, not_null=False
    )
    fqn = col.fqn()
    assert fqn == '"foo"."bar"'
    ```
    """
    return f'"{self._table_name()}"."{self.name}"'