Skip to content

table_base

Base class for table definitions.

TableBase

Base class for Table classes.

The split between Table and TableBase is a bit arbitrary, mostly dictated by preventing circular imports.

Source code in src/embar/table_base.py
10
11
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
class TableBase:
    """
    Base class for `Table` classes.

    The split between `Table` and `TableBase` is a bit arbitrary, mostly
    dictated by preventing circular imports.
    """

    embar_config: EmbarConfig = Undefined
    _fields: ClassVar[dict[str, ColumnBase]]

    @classmethod
    def get_name(cls) -> str:
        """
        Get the table's _database_ name.
        """
        return cls.embar_config.table_name

    @classmethod
    def fqn(cls) -> str:
        """
        Get the "Fully Qualified Name" of the table (i.e. with quotes).
        """
        return f'"{cls.embar_config.table_name}"'

    @classmethod
    def column_names(cls) -> dict[str, str]:
        """
        Mapping of field names to _unquoted_ column names.

        Column names are allowed to be different to field names, so in queries
        we always need to map one to/from the other.
        """
        cols = {name: col.info.name for name, col in cls._fields.items()}
        return cols

    @classmethod
    def returning_clause(cls) -> str:
        """
        Build a ``RETURNING`` clause that aliases every DB column back to its
        Python field name.

        When field name and DB column name are the same this produces::

            RETURNING "id", "content"

        When they differ (e.g. ``email`` → ``user_email``) this produces::

            RETURNING "user_email" AS "email", "id"

        Using explicit aliases instead of ``RETURNING *`` ensures that
        ``load_results`` can always match columns to model fields by their
        Python field names, regardless of any custom DB column name.
        """
        parts: list[str] = []
        for field_name, col in cls._fields.items():
            db_col = col.info.name
            if db_col == field_name:
                parts.append(f'"{db_col}"')
            else:
                parts.append(f'"{db_col}" AS "{field_name}"')
        return "RETURNING " + ", ".join(parts)

column_names() classmethod

Mapping of field names to unquoted column names.

Column names are allowed to be different to field names, so in queries we always need to map one to/from the other.

Source code in src/embar/table_base.py
35
36
37
38
39
40
41
42
43
44
@classmethod
def column_names(cls) -> dict[str, str]:
    """
    Mapping of field names to _unquoted_ column names.

    Column names are allowed to be different to field names, so in queries
    we always need to map one to/from the other.
    """
    cols = {name: col.info.name for name, col in cls._fields.items()}
    return cols

fqn() classmethod

Get the "Fully Qualified Name" of the table (i.e. with quotes).

Source code in src/embar/table_base.py
28
29
30
31
32
33
@classmethod
def fqn(cls) -> str:
    """
    Get the "Fully Qualified Name" of the table (i.e. with quotes).
    """
    return f'"{cls.embar_config.table_name}"'

get_name() classmethod

Get the table's database name.

Source code in src/embar/table_base.py
21
22
23
24
25
26
@classmethod
def get_name(cls) -> str:
    """
    Get the table's _database_ name.
    """
    return cls.embar_config.table_name

returning_clause() classmethod

Build a RETURNING clause that aliases every DB column back to its Python field name.

When field name and DB column name are the same this produces::

RETURNING "id", "content"

When they differ (e.g. emailuser_email) this produces::

RETURNING "user_email" AS "email", "id"

Using explicit aliases instead of RETURNING * ensures that load_results can always match columns to model fields by their Python field names, regardless of any custom DB column name.

Source code in src/embar/table_base.py
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
@classmethod
def returning_clause(cls) -> str:
    """
    Build a ``RETURNING`` clause that aliases every DB column back to its
    Python field name.

    When field name and DB column name are the same this produces::

        RETURNING "id", "content"

    When they differ (e.g. ``email`` → ``user_email``) this produces::

        RETURNING "user_email" AS "email", "id"

    Using explicit aliases instead of ``RETURNING *`` ensures that
    ``load_results`` can always match columns to model fields by their
    Python field names, regardless of any custom DB column name.
    """
    parts: list[str] = []
    for field_name, col in cls._fields.items():
        db_col = col.info.name
        if db_col == field_name:
            parts.append(f'"{db_col}"')
        else:
            parts.append(f'"{db_col}" AS "{field_name}"')
    return "RETURNING " + ", ".join(parts)