Module pyracmon.model

Expand source code
from collections import OrderedDict
from collections.abc import Iterator, Sequence
from typing import Any, Union, Optional, Callable, Generic, TypeVar, get_origin, get_args, cast, TYPE_CHECKING
from typing_extensions import TypeVarTuple, Unpack, Self, dataclass_transform
from .util import PKS


#----------------------------------------------------------------
# Pseudo types used only for type hinting.
#----------------------------------------------------------------
M = TypeVar('M')
MXS = TypeVarTuple('MXS')
COLUMN = NotImplemented


class Mixins(Generic[Unpack[MXS]]):
    pass
MXT = TypeVar('MXT', bound=Mixins)


if TYPE_CHECKING:
    @dataclass_transform(kw_only_default=True)
    class Meta(type):
        #: Table name.
        name: str
        #: `Table` object.
        table: 'Table'
        #: A list of `Column` s.
        columns: list['Column']
        #: An object exposing `Column` object via the attribute of its name.
        column: Any

        def __iter__(self) -> Iterator[tuple['Column', Any]]: ...
        def __getitem__(self, key: str) -> Any: ...
        def __contains__(self, key) -> bool: ...

        @classmethod
        def shrink(cls, excludes, includes=None) -> Self: ...


    class Model(Mixins[Unpack[MXS]], metaclass=Meta):
        """
        Base type of model types.

        This class only works as a marker of model types and gives no functionalities to them.
        """
        def __init__(self, **kwargs) -> None: ... # for typing
else:
    class Meta:
        pass
    class Model:
        pass
#----------------------------------------------------------------
Record = Union[Meta, dict[str, Any]]
"""Model object or dict corresponding to a table row."""


class ForeignKey:
    """
    This class represents a foreign key constraint.
    """
    def __init__(self, table: Union['Table', str], column: Union[str, 'Column']) -> None:
        #: Referenced table model, table name is set alternatively when the table is not modelled.
        self.table = table
        #: Referenced column model, column name is set alternatively when the column is not modelled.
        self.column = column


class Relations:
    """
    This class represents foreign key constraints on a column.
    """
    def __init__(self) -> None:
        #: Foreign key constraints on a column.
        self.constraints: list[ForeignKey] = []

    def add(self, fk: ForeignKey):
        """
        Adds a constraint.

        Args:
            fk: Foreign key constraint.
        """
        self.constraints.append(fk)


class Column:
    """
    This class represents a schema of a column.
    """
    def __init__(
        self,
        name: str,
        ptype: type,
        type_info: Optional[Any],
        pk: bool,
        fk: Optional[Relations],
        incremental: Optional[Any],
        nullable: bool,
        comment: str = "",
    ):
        #: Column name.
        self.name = name
        #: Data type in python.
        self.ptype = ptype
        #: Type informations obtained from DB.
        self.type_info = type_info
        #: Is this column a primary key?
        self.pk = pk
        #: Foreign key constraints.
        self.fk = fk
        #: If this column is auto-incremental, this object contains the information of the feature, otherwise, `None`.
        self.incremental = incremental
        #: Can this column contain null?
        self.nullable = nullable
        #: Comment of the column.
        self.comment = comment


class Table:
    """
    This class represents a schema of a table.
    """
    def __init__(self, name: str, columns: list[Column], comment: str = ""):
        #: Table name.
        self.name = name
        #: Columns in the table.
        self.columns = columns
        #: Comment of the table.
        self.comment = comment

    def find(self, name: str) -> Optional[Column]:
        """
        Find a column by name.

        Args:
            name: Column name.
        Returns:
            The column if exists, otherwise `None`.
        """
        return next(filter(lambda c: c.name == name, self.columns), None)


def define_model(table_: Table, mixins: Union[type[MXT], list[type], None] = None, model_type: Optional[type[M]] = Model) -> type[M]:
    """
    Create a model type representing a table.

    Model type inherits all types in `mixins` in order.
    When the same attribute is defined in multiple mixin types, the former overrides the latter.

    Every model type has following attributes:

    |name|type|description|
    |:---|:---|:---|
    |name|`str`|Name of the table.|
    |table|`Table`|Table schema.|
    |columns|`List[Column]`|List of column schemas.|
    |column|`Any`|An object whose attribute exposes of column schema of its name.|

    Model instances are created by passing the constructor keyword arguments composed of column names and values like builtin dataclass.
    Unlike dataclass, the constructor does not require all of columns.
    Omitted columns don't affect predefined operations such as `CRUDMixin.insert` .
    If `not null` constraint exists on the column, insertion will be denied at runtime and exception will be thrown.

    ```python
    >>> # CREATE TABLE t1 (col1 int, col2 text, col3 text);
    >>> table = define_model("t1")
    >>> model = table(col1=1, col2="a")
    ```

    Attributes are also assignable by normal setter. If attribute name is not a valid column name, `TypeError` raises.

    ```python
    >>> model.col3 = "b"
    ```

    Model instance supports iteration which yields pairs of assigned column schema and its value.

    ```python
    >>> for c, v in model:
    >>>     print(f"{c.name} = {v}")
    col1 = 1
    col2 = a
    col3 = b
    ```

    Args:
        table__: Table schema.
        mixin: Mixin types providing class methods to the model type.
        model_type: Use this just for type hinting to determine returned model type.
    Returns:
        Model type.
    """
    column_names = {c.name for c in table_.columns}

    class Columns:
        def __init__(self):
            for c in table_.columns:
                setattr(self, c.name, c)

    class Meta(type):
        name = table_.name
        table = table_
        columns = table_.columns
        column = Columns()

        @classmethod
        def shrink(cls, excludes: list[str], includes: Optional[list[str]] = None) -> Self:
            """
            Creates new model type containing subset of columns.

            Args:
                excludes: Column names to exclude.
                includes: Column names to include.
            Returns:
                model type.
            """
            cols = [c for c in cls.columns if (not includes or c.name in includes) and c.name not in excludes]
            return define_model(Table(cls.name, cols, cls.table.comment), mixins) # type: ignore

    class Base(Model, metaclass=Meta):
        pass

    mixin_types: list[type] = []

    if isinstance(mixins, list):
        mixin_types = mixins
    elif get_origin(mixins) is not None:
        mixin_types = cast(list[type], list(get_args(mixins)))
    elif mixins is not None:
        raise ValueError(f"Model mixin types should be specified by Mixins or a list of types.")

    class _Model(type("ModelBase", tuple([Base] + mixin_types), {})):
        def __init__(self, **kwargs):
            for k, v in kwargs.items():
                setattr(self, k, v)

        def __repr__(self):
            cls = cast(type[Base], type(self))
            return f"{cls.name}({', '.join([f'{c.name}={repr(getattr(self, c.name))}' for c in cls.columns if hasattr(self, c.name)])})"

        def __str__(self):
            cls = cast(type[Base], type(self))
            return f"{cls.name}({', '.join([f'{c.name}={str(getattr(self, c.name))}' for c in cls.columns if hasattr(self, c.name)])})"

        def __iter__(self) -> Iterator[tuple[Column, Any]]:
            cls = cast(type[Base], type(self))
            return map(lambda c: (c, getattr(self, c.name)), filter(lambda c: hasattr(self, c.name), cls.columns))

        def __setattr__(self, key, value):
            cls = cast(type[Base], type(self))
            if key not in column_names:
                raise TypeError(f"{key} is not a column of {cls.name}")
            object.__setattr__(self, key, value)

        def __getitem__(self, key):
            return getattr(self, key)

        def __contains__(self, key):
            return hasattr(self, key)

        def __eq__(self, other):
            cls = type(self)
            if cls != type(other):
                return False
            for k in column_names:
                if hasattr(self, k) ^ hasattr(other, k):
                    return False
                if getattr(self, k, None) != getattr(other, k, None):
                    return False
            return True

    return cast(type[M], _Model)


def parse_pks(model: type[Meta], pks: PKS) -> tuple[list[str], list[Any]]:
    """
    Generates a pair of PK columns names and their values from polymorphic input.

    Args:
        model: Model class.
        pks: A dictionary of PK column name and their values or an object of single PK column.
    Returns:
        Names of PK columns and their values.
    """
    if isinstance(pks, dict):
        ordered = check_columns(model, pks, lambda c: c.pk, True)
        return [v[0] for v in ordered], [v[1] for v in ordered]
    else:
        cols = [c.name for c in model.columns if c.pk]
        if len(cols) != 1:
            raise ValueError(f"The number of primary key columns in {model.name} is not 1.")
        return ([cols[0]], [pks])


def extract_pks(model: type[Meta], record: Record) -> PKS:
    """
    Extract all primary keys from a record.

    Args:
        model: Model class.
        record: A record.
    Returns:
        Primary keys.
    """
    pk_columns = [c.name for c in model.columns if c.pk]
    if isinstance(record, dict):
        pks = dict((c, record[c]) for c in pk_columns if c in record)
    else:
        pks = dict((c, getattr(record, c)) for c in pk_columns if hasattr(record, c))
    if len(pks) != len(pk_columns):
        missing = set(pk_columns) - set(pks.keys())
        raise ValueError(f"Some primary keys are not contained in passed values and auto-increment values: {missing}")
    return pks


def check_columns(
    model: type[Meta],
    col_map: dict[str, Any],
    condition: Callable[[Column], bool] = lambda c: True,
    requires_all: bool = False,
) -> list[tuple[str, Any]]:
    """
    Checks keys of given `dict` match columns selected by a condition from a model.

    Args:
        model: Model class.
        col_map: Dictionary whose keys are column names.
        condition: A function which selects columns from the model.
        requires_all: If `True`, `ValueError` raises when the dictionary does not contain keys of all selected columns.
    """
    names = [c.name for c in model.columns if condition(c)]
    name_set = set(names)
    targets = set(col_map.keys())
    if not name_set >= targets:
        raise ValueError(f"Columns {targets - name_set} are not specified columns of '{model.name}'.")
    if requires_all and not name_set == targets:
        raise ValueError(f"Required columns {name_set - targets} in '{model.name}' are not found.")
    return [(n, col_map[n]) for n in names if n in col_map]


def model_values(model: type[Meta], values: Record, excludes_pk: bool = False) -> dict[str, Any]:
    """
    Generates a dictionary whose items are pairs of column name and column value.

    Args:
        model: Model class.
        values: Dictionary from column name to column value or a model instance.
        excludes_pk: If `True`, item of PK column is not contained in returned dictionary.
    Returns:
        A dictionary from column name to column value.
    """
    if isinstance(values, (dict, OrderedDict)):
        includes = {c.name for c in model.columns if (not excludes_pk) or (not c.pk)}
        return {k:v for k, v in values.items() if k in includes}
    elif isinstance(values, model):
        return {cv[0].name:cv[1] for cv in values if (not excludes_pk) or (not cv[0].pk)}
    else:
        raise TypeError(f"Required column value is not contained in the dictionary or model.")

Global variables

var Record

Model object or dict corresponding to a table row.

Functions

def check_columns(model: type[Meta], col_map: dict[str, typing.Any], condition: Callable[[Column], bool] = <function <lambda>>, requires_all: bool = False) ‑> list[tuple[str, typing.Any]]

Checks keys of given dict match columns selected by a condition from a model.

Args

model
Model class.
col_map
Dictionary whose keys are column names.
condition
A function which selects columns from the model.
requires_all
If True, ValueError raises when the dictionary does not contain keys of all selected columns.
Expand source code
def check_columns(
    model: type[Meta],
    col_map: dict[str, Any],
    condition: Callable[[Column], bool] = lambda c: True,
    requires_all: bool = False,
) -> list[tuple[str, Any]]:
    """
    Checks keys of given `dict` match columns selected by a condition from a model.

    Args:
        model: Model class.
        col_map: Dictionary whose keys are column names.
        condition: A function which selects columns from the model.
        requires_all: If `True`, `ValueError` raises when the dictionary does not contain keys of all selected columns.
    """
    names = [c.name for c in model.columns if condition(c)]
    name_set = set(names)
    targets = set(col_map.keys())
    if not name_set >= targets:
        raise ValueError(f"Columns {targets - name_set} are not specified columns of '{model.name}'.")
    if requires_all and not name_set == targets:
        raise ValueError(f"Required columns {name_set - targets} in '{model.name}' are not found.")
    return [(n, col_map[n]) for n in names if n in col_map]
def define_model(table_: Table, mixins: Union[type[~MXT], list[type], ForwardRef(None)] = None, model_type: Optional[type[~M]] = pyracmon.model.Model) ‑> type[~M]

Create a model type representing a table.

Model type inherits all types in mixins in order. When the same attribute is defined in multiple mixin types, the former overrides the latter.

Every model type has following attributes:

name type description
name str Name of the table.
table Table Table schema.
columns List[Column] List of column schemas.
column Any An object whose attribute exposes of column schema of its name.

Model instances are created by passing the constructor keyword arguments composed of column names and values like builtin dataclass. Unlike dataclass, the constructor does not require all of columns. Omitted columns don't affect predefined operations such as CRUDMixin.insert . If not null constraint exists on the column, insertion will be denied at runtime and exception will be thrown.

>>> # CREATE TABLE t1 (col1 int, col2 text, col3 text);
>>> table = define_model("t1")
>>> model = table(col1=1, col2="a")

Attributes are also assignable by normal setter. If attribute name is not a valid column name, TypeError raises.

>>> model.col3 = "b"

Model instance supports iteration which yields pairs of assigned column schema and its value.

>>> for c, v in model:
>>>     print(f"{c.name} = {v}")
col1 = 1
col2 = a
col3 = b

Args

table__
Table schema.
mixin
Mixin types providing class methods to the model type.
model_type
Use this just for type hinting to determine returned model type.

Returns

Model type.

Expand source code
def define_model(table_: Table, mixins: Union[type[MXT], list[type], None] = None, model_type: Optional[type[M]] = Model) -> type[M]:
    """
    Create a model type representing a table.

    Model type inherits all types in `mixins` in order.
    When the same attribute is defined in multiple mixin types, the former overrides the latter.

    Every model type has following attributes:

    |name|type|description|
    |:---|:---|:---|
    |name|`str`|Name of the table.|
    |table|`Table`|Table schema.|
    |columns|`List[Column]`|List of column schemas.|
    |column|`Any`|An object whose attribute exposes of column schema of its name.|

    Model instances are created by passing the constructor keyword arguments composed of column names and values like builtin dataclass.
    Unlike dataclass, the constructor does not require all of columns.
    Omitted columns don't affect predefined operations such as `CRUDMixin.insert` .
    If `not null` constraint exists on the column, insertion will be denied at runtime and exception will be thrown.

    ```python
    >>> # CREATE TABLE t1 (col1 int, col2 text, col3 text);
    >>> table = define_model("t1")
    >>> model = table(col1=1, col2="a")
    ```

    Attributes are also assignable by normal setter. If attribute name is not a valid column name, `TypeError` raises.

    ```python
    >>> model.col3 = "b"
    ```

    Model instance supports iteration which yields pairs of assigned column schema and its value.

    ```python
    >>> for c, v in model:
    >>>     print(f"{c.name} = {v}")
    col1 = 1
    col2 = a
    col3 = b
    ```

    Args:
        table__: Table schema.
        mixin: Mixin types providing class methods to the model type.
        model_type: Use this just for type hinting to determine returned model type.
    Returns:
        Model type.
    """
    column_names = {c.name for c in table_.columns}

    class Columns:
        def __init__(self):
            for c in table_.columns:
                setattr(self, c.name, c)

    class Meta(type):
        name = table_.name
        table = table_
        columns = table_.columns
        column = Columns()

        @classmethod
        def shrink(cls, excludes: list[str], includes: Optional[list[str]] = None) -> Self:
            """
            Creates new model type containing subset of columns.

            Args:
                excludes: Column names to exclude.
                includes: Column names to include.
            Returns:
                model type.
            """
            cols = [c for c in cls.columns if (not includes or c.name in includes) and c.name not in excludes]
            return define_model(Table(cls.name, cols, cls.table.comment), mixins) # type: ignore

    class Base(Model, metaclass=Meta):
        pass

    mixin_types: list[type] = []

    if isinstance(mixins, list):
        mixin_types = mixins
    elif get_origin(mixins) is not None:
        mixin_types = cast(list[type], list(get_args(mixins)))
    elif mixins is not None:
        raise ValueError(f"Model mixin types should be specified by Mixins or a list of types.")

    class _Model(type("ModelBase", tuple([Base] + mixin_types), {})):
        def __init__(self, **kwargs):
            for k, v in kwargs.items():
                setattr(self, k, v)

        def __repr__(self):
            cls = cast(type[Base], type(self))
            return f"{cls.name}({', '.join([f'{c.name}={repr(getattr(self, c.name))}' for c in cls.columns if hasattr(self, c.name)])})"

        def __str__(self):
            cls = cast(type[Base], type(self))
            return f"{cls.name}({', '.join([f'{c.name}={str(getattr(self, c.name))}' for c in cls.columns if hasattr(self, c.name)])})"

        def __iter__(self) -> Iterator[tuple[Column, Any]]:
            cls = cast(type[Base], type(self))
            return map(lambda c: (c, getattr(self, c.name)), filter(lambda c: hasattr(self, c.name), cls.columns))

        def __setattr__(self, key, value):
            cls = cast(type[Base], type(self))
            if key not in column_names:
                raise TypeError(f"{key} is not a column of {cls.name}")
            object.__setattr__(self, key, value)

        def __getitem__(self, key):
            return getattr(self, key)

        def __contains__(self, key):
            return hasattr(self, key)

        def __eq__(self, other):
            cls = type(self)
            if cls != type(other):
                return False
            for k in column_names:
                if hasattr(self, k) ^ hasattr(other, k):
                    return False
                if getattr(self, k, None) != getattr(other, k, None):
                    return False
            return True

    return cast(type[M], _Model)
def extract_pks(model: type[Meta], record: Union[Meta, dict[str, Any]]) ‑> Union[Any, dict[str, Any]]

Extract all primary keys from a record.

Args

model
Model class.
record
A record.

Returns

Primary keys.

Expand source code
def extract_pks(model: type[Meta], record: Record) -> PKS:
    """
    Extract all primary keys from a record.

    Args:
        model: Model class.
        record: A record.
    Returns:
        Primary keys.
    """
    pk_columns = [c.name for c in model.columns if c.pk]
    if isinstance(record, dict):
        pks = dict((c, record[c]) for c in pk_columns if c in record)
    else:
        pks = dict((c, getattr(record, c)) for c in pk_columns if hasattr(record, c))
    if len(pks) != len(pk_columns):
        missing = set(pk_columns) - set(pks.keys())
        raise ValueError(f"Some primary keys are not contained in passed values and auto-increment values: {missing}")
    return pks
def model_values(model: type[Meta], values: Union[Meta, dict[str, Any]], excludes_pk: bool = False) ‑> dict[str, typing.Any]

Generates a dictionary whose items are pairs of column name and column value.

Args

model
Model class.
values
Dictionary from column name to column value or a model instance.
excludes_pk
If True, item of PK column is not contained in returned dictionary.

Returns

A dictionary from column name to column value.

Expand source code
def model_values(model: type[Meta], values: Record, excludes_pk: bool = False) -> dict[str, Any]:
    """
    Generates a dictionary whose items are pairs of column name and column value.

    Args:
        model: Model class.
        values: Dictionary from column name to column value or a model instance.
        excludes_pk: If `True`, item of PK column is not contained in returned dictionary.
    Returns:
        A dictionary from column name to column value.
    """
    if isinstance(values, (dict, OrderedDict)):
        includes = {c.name for c in model.columns if (not excludes_pk) or (not c.pk)}
        return {k:v for k, v in values.items() if k in includes}
    elif isinstance(values, model):
        return {cv[0].name:cv[1] for cv in values if (not excludes_pk) or (not cv[0].pk)}
    else:
        raise TypeError(f"Required column value is not contained in the dictionary or model.")
def parse_pks(model: type[Meta], pks: Union[Any, dict[str, Any]]) ‑> tuple[list[str], list[typing.Any]]

Generates a pair of PK columns names and their values from polymorphic input.

Args

model
Model class.
pks
A dictionary of PK column name and their values or an object of single PK column.

Returns

Names of PK columns and their values.

Expand source code
def parse_pks(model: type[Meta], pks: PKS) -> tuple[list[str], list[Any]]:
    """
    Generates a pair of PK columns names and their values from polymorphic input.

    Args:
        model: Model class.
        pks: A dictionary of PK column name and their values or an object of single PK column.
    Returns:
        Names of PK columns and their values.
    """
    if isinstance(pks, dict):
        ordered = check_columns(model, pks, lambda c: c.pk, True)
        return [v[0] for v in ordered], [v[1] for v in ordered]
    else:
        cols = [c.name for c in model.columns if c.pk]
        if len(cols) != 1:
            raise ValueError(f"The number of primary key columns in {model.name} is not 1.")
        return ([cols[0]], [pks])

Classes

class Column (name: str, ptype: type, type_info: Optional[Any], pk: bool, fk: Optional[Relations], incremental: Optional[Any], nullable: bool, comment: str = '')

This class represents a schema of a column.

Expand source code
class Column:
    """
    This class represents a schema of a column.
    """
    def __init__(
        self,
        name: str,
        ptype: type,
        type_info: Optional[Any],
        pk: bool,
        fk: Optional[Relations],
        incremental: Optional[Any],
        nullable: bool,
        comment: str = "",
    ):
        #: Column name.
        self.name = name
        #: Data type in python.
        self.ptype = ptype
        #: Type informations obtained from DB.
        self.type_info = type_info
        #: Is this column a primary key?
        self.pk = pk
        #: Foreign key constraints.
        self.fk = fk
        #: If this column is auto-incremental, this object contains the information of the feature, otherwise, `None`.
        self.incremental = incremental
        #: Can this column contain null?
        self.nullable = nullable
        #: Comment of the column.
        self.comment = comment

Instance variables

var comment

Comment of the column.

var fk

Foreign key constraints.

var incremental

If this column is auto-incremental, this object contains the information of the feature, otherwise, None.

var name

Column name.

var nullable

Can this column contain null?

var pk

Is this column a primary key?

var ptype

Data type in python.

var type_info

Type informations obtained from DB.

class ForeignKey (table: Union[ForwardRef('Table'), str], column: Union[str, ForwardRef('Column')])

This class represents a foreign key constraint.

Expand source code
class ForeignKey:
    """
    This class represents a foreign key constraint.
    """
    def __init__(self, table: Union['Table', str], column: Union[str, 'Column']) -> None:
        #: Referenced table model, table name is set alternatively when the table is not modelled.
        self.table = table
        #: Referenced column model, column name is set alternatively when the column is not modelled.
        self.column = column

Instance variables

var column

Referenced column model, column name is set alternatively when the column is not modelled.

var table

Referenced table model, table name is set alternatively when the table is not modelled.

class Meta
Expand source code
@dataclass_transform(kw_only_default=True)
class Meta(type):
    #: Table name.
    name: str
    #: `Table` object.
    table: 'Table'
    #: A list of `Column` s.
    columns: list['Column']
    #: An object exposing `Column` object via the attribute of its name.
    column: Any

    def __iter__(self) -> Iterator[tuple['Column', Any]]: ...
    def __getitem__(self, key: str) -> Any: ...
    def __contains__(self, key) -> bool: ...

    @classmethod
    def shrink(cls, excludes, includes=None) -> Self: ...

Subclasses

class Mixins

Abstract base class for generic types.

A generic type is typically declared by inheriting from this class parameterized with one or more type variables. For example, a generic mapping type might be defined as::

class Mapping(Generic[KT, VT]): def getitem(self, key: KT) -> VT: … # Etc.

This class can then be used as follows::

def lookup_name(mapping: Mapping[KT, VT], key: KT, default: VT) -> VT: try: return mapping[key] except KeyError: return default

Expand source code
class Mixins(Generic[Unpack[MXS]]):
    pass

Ancestors

  • typing.Generic
class Model
Expand source code
class Model(Mixins[Unpack[MXS]], metaclass=Meta):
    """
    Base type of model types.

    This class only works as a marker of model types and gives no functionalities to them.
    """
    def __init__(self, **kwargs) -> None: ... # for typing
class Relations

This class represents foreign key constraints on a column.

Expand source code
class Relations:
    """
    This class represents foreign key constraints on a column.
    """
    def __init__(self) -> None:
        #: Foreign key constraints on a column.
        self.constraints: list[ForeignKey] = []

    def add(self, fk: ForeignKey):
        """
        Adds a constraint.

        Args:
            fk: Foreign key constraint.
        """
        self.constraints.append(fk)

Instance variables

var constraints

Foreign key constraints on a column.

Methods

def add(self, fk: ForeignKey)

Adds a constraint.

Args

fk
Foreign key constraint.
Expand source code
def add(self, fk: ForeignKey):
    """
    Adds a constraint.

    Args:
        fk: Foreign key constraint.
    """
    self.constraints.append(fk)
class Table (name: str, columns: list[Column], comment: str = '')

This class represents a schema of a table.

Expand source code
class Table:
    """
    This class represents a schema of a table.
    """
    def __init__(self, name: str, columns: list[Column], comment: str = ""):
        #: Table name.
        self.name = name
        #: Columns in the table.
        self.columns = columns
        #: Comment of the table.
        self.comment = comment

    def find(self, name: str) -> Optional[Column]:
        """
        Find a column by name.

        Args:
            name: Column name.
        Returns:
            The column if exists, otherwise `None`.
        """
        return next(filter(lambda c: c.name == name, self.columns), None)

Instance variables

var columns

Columns in the table.

var comment

Comment of the table.

var name

Table name.

Methods

def find(self, name: str) ‑> Optional[Column]

Find a column by name.

Args

name
Column name.

Returns

The column if exists, otherwise None.

Expand source code
def find(self, name: str) -> Optional[Column]:
    """
    Find a column by name.

    Args:
        name: Column name.
    Returns:
        The column if exists, otherwise `None`.
    """
    return next(filter(lambda c: c.name == name, self.columns), None)