Skip to content

API Reference

Database Constants

DatabaseConnectionType

Bases: Enum

Enum for database connection types.

Source code in src/supabase_pydantic/db/constants.py
class DatabaseConnectionType(Enum):
    """Enum for database connection types."""

    LOCAL = 'local'
    DB_URL = 'db_url'

DatabaseUserDefinedType

Bases: str, Enum

Enum for database user defined types.

Source code in src/supabase_pydantic/db/constants.py
class DatabaseUserDefinedType(str, Enum):
    """Enum for database user defined types."""

    DOMAIN = 'DOMAIN'
    COMPOSITE = 'COMPOSITE'
    ENUM = 'ENUM'
    RANGE = 'RANGE'

RelationType

Bases: str, Enum

Enum for relation types.

Source code in src/supabase_pydantic/db/constants.py
class RelationType(str, Enum):
    """Enum for relation types."""

    ONE_TO_ONE = 'One-to-One'
    ONE_TO_MANY = 'One-to-Many'
    MANY_TO_MANY = 'Many-to-Many'
    MANY_TO_ONE = 'Many-to-One'  # When a table has a foreign key to another table (e.g., File -> Project)

Core Constants

FrameWorkType

Bases: Enum

Enum for framework types.

Source code in src/supabase_pydantic/core/constants.py
class FrameWorkType(Enum):
    """Enum for framework types."""

    FASTAPI = 'fastapi'

OrmType

Bases: Enum

Enum for file types.

Source code in src/supabase_pydantic/core/constants.py
4
5
6
7
8
class OrmType(Enum):
    """Enum for file types."""

    PYDANTIC = 'pydantic'
    SQLALCHEMY = 'sqlalchemy'

WriterClassType

Bases: Enum

Enum for writer class types.

Source code in src/supabase_pydantic/core/constants.py
class WriterClassType(Enum):
    """Enum for writer class types."""

    BASE = 'base'  # The main Row model with all fields
    BASE_WITH_PARENT = 'base_with_parent'
    PARENT = 'parent'
    INSERT = 'insert'  # Model for insert operations - auto-generated fields optional
    UPDATE = 'update'  # Model for update operations - all fields optional

Utility Constants

AppConfig

Bases: TypedDict

Configuration for the Supabase Pydantic tool.

Source code in src/supabase_pydantic/utils/constants.py
class AppConfig(TypedDict, total=False):
    """Configuration for the Supabase Pydantic tool."""

    default_directory: str
    overwrite_existing_files: bool
    nullify_base_schema: bool
    disable_model_prefix_protection: bool

ToolConfig

Bases: TypedDict

Configuration for the Supabase Pydantic tool.

Source code in src/supabase_pydantic/utils/constants.py
class ToolConfig(TypedDict):
    """Configuration for the Supabase Pydantic tool."""

    supabase_pydantic: AppConfig

Database Models

ColumnInfo dataclass

Bases: AsDictParent

Column information.

Source code in src/supabase_pydantic/db/models.py
@dataclass
class ColumnInfo(AsDictParent):
    """Column information."""

    name: str
    post_gres_datatype: str
    datatype: str
    user_defined_values: list[str] | None = field(default_factory=list)
    unique_partners: list[str] | None = field(default_factory=list)
    alias: str | None = None
    default: str | None = None
    max_length: int | None = None
    is_nullable: bool | None = True
    primary: bool = False
    is_unique: bool = False
    is_foreign_key: bool = False
    constraint_definition: str | None = None
    is_identity: bool = False  # For auto-generated identity columns
    enum_info: EnumInfo | None = None  # New field for enum metadata
    array_element_type: str | None = None  # Stores element type for array columns

    def __str__(self) -> str:
        """Return a string representation of the column."""
        return f'ColumnInfo({self.name}, {self.post_gres_datatype})'

    @property
    def has_default(self) -> bool:
        """Check if the column has a default value."""
        return self.default is not None

    @property
    def is_generated(self) -> bool:
        """Check if the column is auto-generated (identity or serial)."""
        return self.is_identity or (self.default is not None and 'nextval' in str(self.default).lower())

    def orm_imports(self, orm_type: OrmType = OrmType.PYDANTIC) -> set[str | None]:
        """Get the unique import statements for a column."""
        imports = set()  # future proofing in case multiple imports are needed
        if orm_type == OrmType.SQLALCHEMY:
            i = get_sqlalchemy_type(self.post_gres_datatype, ('Any', 'from sqlalchemy import Column'))[1]
        else:
            i = get_pydantic_type(self.post_gres_datatype)[1]
        imports.add(i)
        return imports

    def orm_datatype(self, orm_type: OrmType = OrmType.PYDANTIC) -> str:
        """Get the datatype for a column."""
        if orm_type == OrmType.SQLALCHEMY:
            sql_datatype: str = get_sqlalchemy_type(self.post_gres_datatype)[0]
            return sql_datatype

        pydantic_datatype: str = get_pydantic_type(self.post_gres_datatype)[0]
        return pydantic_datatype

    def is_user_defined_type(self) -> bool:
        """Check if the column is a user-defined type."""
        return self.post_gres_datatype == 'USER-DEFINED'

    def nullable(self) -> bool:
        """Check if the column is nullable."""
        return self.is_nullable if self.is_nullable is not None else False

has_default property

Check if the column has a default value.

is_generated property

Check if the column is auto-generated (identity or serial).

__str__()

Return a string representation of the column.

Source code in src/supabase_pydantic/db/models.py
def __str__(self) -> str:
    """Return a string representation of the column."""
    return f'ColumnInfo({self.name}, {self.post_gres_datatype})'

is_user_defined_type()

Check if the column is a user-defined type.

Source code in src/supabase_pydantic/db/models.py
def is_user_defined_type(self) -> bool:
    """Check if the column is a user-defined type."""
    return self.post_gres_datatype == 'USER-DEFINED'

nullable()

Check if the column is nullable.

Source code in src/supabase_pydantic/db/models.py
def nullable(self) -> bool:
    """Check if the column is nullable."""
    return self.is_nullable if self.is_nullable is not None else False

orm_datatype(orm_type=OrmType.PYDANTIC)

Get the datatype for a column.

Source code in src/supabase_pydantic/db/models.py
def orm_datatype(self, orm_type: OrmType = OrmType.PYDANTIC) -> str:
    """Get the datatype for a column."""
    if orm_type == OrmType.SQLALCHEMY:
        sql_datatype: str = get_sqlalchemy_type(self.post_gres_datatype)[0]
        return sql_datatype

    pydantic_datatype: str = get_pydantic_type(self.post_gres_datatype)[0]
    return pydantic_datatype

orm_imports(orm_type=OrmType.PYDANTIC)

Get the unique import statements for a column.

Source code in src/supabase_pydantic/db/models.py
def orm_imports(self, orm_type: OrmType = OrmType.PYDANTIC) -> set[str | None]:
    """Get the unique import statements for a column."""
    imports = set()  # future proofing in case multiple imports are needed
    if orm_type == OrmType.SQLALCHEMY:
        i = get_sqlalchemy_type(self.post_gres_datatype, ('Any', 'from sqlalchemy import Column'))[1]
    else:
        i = get_pydantic_type(self.post_gres_datatype)[1]
    imports.add(i)
    return imports

ConstraintInfo dataclass

Bases: AsDictParent

Source code in src/supabase_pydantic/db/models.py
@dataclass
class ConstraintInfo(AsDictParent):
    constraint_name: str
    raw_constraint_type: str
    constraint_definition: str
    columns: list[str] = field(default_factory=list)

    def constraint_type(self) -> str:
        """Get the constraint type."""
        constraint_type: str = CONSTRAINT_TYPE_MAP.get(self.raw_constraint_type.lower(), 'OTHER')
        return constraint_type

    def __str__(self) -> str:
        """Return a string representation of the constraint."""
        return f'ConstraintInfo({self.constraint_name}, {self.constraint_type()})'

__str__()

Return a string representation of the constraint.

Source code in src/supabase_pydantic/db/models.py
def __str__(self) -> str:
    """Return a string representation of the constraint."""
    return f'ConstraintInfo({self.constraint_name}, {self.constraint_type()})'

constraint_type()

Get the constraint type.

Source code in src/supabase_pydantic/db/models.py
def constraint_type(self) -> str:
    """Get the constraint type."""
    constraint_type: str = CONSTRAINT_TYPE_MAP.get(self.raw_constraint_type.lower(), 'OTHER')
    return constraint_type

TableInfo dataclass

Bases: AsDictParent

Source code in src/supabase_pydantic/db/models.py
@dataclass
class TableInfo(AsDictParent):
    name: str
    schema: str = 'public'
    table_type: Literal['BASE TABLE', 'VIEW'] = 'BASE TABLE'
    is_bridge: bool = False  # whether the table is a bridge table
    columns: list[ColumnInfo] = field(default_factory=list)
    foreign_keys: list[ForeignKeyInfo] = field(default_factory=list)
    constraints: list[ConstraintInfo] = field(default_factory=list)
    relationships: list[RelationshipInfo] = field(default_factory=list)
    generated_data: list[dict] = field(default_factory=list)

    def __str__(self) -> str:
        """Return a string representation of the table."""
        return f'TableInfo({self.schema}.{self.name})'

    def add_column(self, column: ColumnInfo) -> None:
        """Add a column to the table."""
        self.columns.append(column)

    def add_foreign_key(self, fk: ForeignKeyInfo) -> None:
        """Add a foreign key to the table."""
        self.foreign_keys.append(fk)

    def add_constraint(self, constraint: ConstraintInfo) -> None:
        """Add a constraint to the table."""
        self.constraints.append(constraint)

    def aliasing_in_columns(self) -> bool:
        """Check if any column within a table has an alias."""
        return any(bool(c.alias is not None) for c in self.columns)

    def table_dependencies(self) -> set[str]:
        """Get the table dependencies (foreign tables) for a table."""
        return set([fk.foreign_table_name for fk in self.foreign_keys])

    def primary_key(self) -> list[str]:
        """Get the primary key for a table."""
        if self.table_type == 'BASE TABLE':
            for constraint in self.constraints:
                if constraint.constraint_type() == 'PRIMARY KEY':
                    return constraint.columns
        return []  # Return an empty list if no primary key is found

    def primary_is_composite(self) -> bool:
        """Check if the primary key is composite."""
        return len(self.primary_key()) > 1

    def get_primary_columns(self, sort_results: bool = False) -> list[ColumnInfo]:
        """Get the primary columns for a table."""
        return self._get_columns(is_primary=True, sort_results=sort_results)

    def get_secondary_columns(self, sort_results: bool = False) -> list[ColumnInfo]:
        """Get the secondary columns for a table."""
        return self._get_columns(is_primary=False, sort_results=sort_results)

    def _get_columns(self, is_primary: bool = True, sort_results: bool = False) -> list[ColumnInfo]:
        """Private function to get the primary or secondary columns for a table."""
        if is_primary:
            res = [c for c in self.columns if c.name in self.primary_key()]
        else:
            res = [c for c in self.columns if c.name not in self.primary_key()]

        if sort_results:
            res.sort(key=lambda x: x.name)

        return res

    def sort_and_separate_columns(
        self, separate_nullable: bool = False, separate_primary_key: bool = False
    ) -> SortedColumns:
        """Sort and combine columns based on is_nullable attribute.

        Args:
            separate_nullable: Whether to separate nullable and non-nullable columns.
            separate_primary_key: Whether to separate primary key and secondary columns.

        Returns:
            A dictionary with keys, nullable, non_nullable, and remaining as keys
            and lists of ColumnInfo objects as values.
        """
        # result: dict[str, list[ColumnInfo]] = {'keys': [], 'nullable': [], 'non_nullable': [], 'remaining': []}
        result: SortedColumns = SortedColumns([], [], [], [])
        if separate_primary_key:
            result.primary_keys = self.get_primary_columns(sort_results=True)
            result.remaining = self.get_secondary_columns(sort_results=True)
        else:
            result.remaining = sorted(self.columns, key=lambda x: x.name)

        if separate_nullable:
            nullable_columns = [column for column in result.remaining if column.is_nullable]  # already sorted
            non_nullable_columns = [column for column in result.remaining if not column.is_nullable]

            # Combine them with non-nullable first
            result.nullable = nullable_columns
            result.non_nullable = non_nullable_columns
            result.remaining = []

        return result

    def has_unique_constraint(self) -> bool:
        """Check if the table has unique constraints."""
        return any(c.constraint_type() == 'UNIQUE' for c in self.constraints)

__str__()

Return a string representation of the table.

Source code in src/supabase_pydantic/db/models.py
def __str__(self) -> str:
    """Return a string representation of the table."""
    return f'TableInfo({self.schema}.{self.name})'

add_column(column)

Add a column to the table.

Source code in src/supabase_pydantic/db/models.py
def add_column(self, column: ColumnInfo) -> None:
    """Add a column to the table."""
    self.columns.append(column)

add_constraint(constraint)

Add a constraint to the table.

Source code in src/supabase_pydantic/db/models.py
def add_constraint(self, constraint: ConstraintInfo) -> None:
    """Add a constraint to the table."""
    self.constraints.append(constraint)

add_foreign_key(fk)

Add a foreign key to the table.

Source code in src/supabase_pydantic/db/models.py
def add_foreign_key(self, fk: ForeignKeyInfo) -> None:
    """Add a foreign key to the table."""
    self.foreign_keys.append(fk)

aliasing_in_columns()

Check if any column within a table has an alias.

Source code in src/supabase_pydantic/db/models.py
def aliasing_in_columns(self) -> bool:
    """Check if any column within a table has an alias."""
    return any(bool(c.alias is not None) for c in self.columns)

get_primary_columns(sort_results=False)

Get the primary columns for a table.

Source code in src/supabase_pydantic/db/models.py
def get_primary_columns(self, sort_results: bool = False) -> list[ColumnInfo]:
    """Get the primary columns for a table."""
    return self._get_columns(is_primary=True, sort_results=sort_results)

get_secondary_columns(sort_results=False)

Get the secondary columns for a table.

Source code in src/supabase_pydantic/db/models.py
def get_secondary_columns(self, sort_results: bool = False) -> list[ColumnInfo]:
    """Get the secondary columns for a table."""
    return self._get_columns(is_primary=False, sort_results=sort_results)

has_unique_constraint()

Check if the table has unique constraints.

Source code in src/supabase_pydantic/db/models.py
def has_unique_constraint(self) -> bool:
    """Check if the table has unique constraints."""
    return any(c.constraint_type() == 'UNIQUE' for c in self.constraints)

primary_is_composite()

Check if the primary key is composite.

Source code in src/supabase_pydantic/db/models.py
def primary_is_composite(self) -> bool:
    """Check if the primary key is composite."""
    return len(self.primary_key()) > 1

primary_key()

Get the primary key for a table.

Source code in src/supabase_pydantic/db/models.py
def primary_key(self) -> list[str]:
    """Get the primary key for a table."""
    if self.table_type == 'BASE TABLE':
        for constraint in self.constraints:
            if constraint.constraint_type() == 'PRIMARY KEY':
                return constraint.columns
    return []  # Return an empty list if no primary key is found

sort_and_separate_columns(separate_nullable=False, separate_primary_key=False)

Sort and combine columns based on is_nullable attribute.

Parameters:

Name Type Description Default
separate_nullable bool

Whether to separate nullable and non-nullable columns.

False
separate_primary_key bool

Whether to separate primary key and secondary columns.

False

Returns:

Type Description
SortedColumns

A dictionary with keys, nullable, non_nullable, and remaining as keys

SortedColumns

and lists of ColumnInfo objects as values.

Source code in src/supabase_pydantic/db/models.py
def sort_and_separate_columns(
    self, separate_nullable: bool = False, separate_primary_key: bool = False
) -> SortedColumns:
    """Sort and combine columns based on is_nullable attribute.

    Args:
        separate_nullable: Whether to separate nullable and non-nullable columns.
        separate_primary_key: Whether to separate primary key and secondary columns.

    Returns:
        A dictionary with keys, nullable, non_nullable, and remaining as keys
        and lists of ColumnInfo objects as values.
    """
    # result: dict[str, list[ColumnInfo]] = {'keys': [], 'nullable': [], 'non_nullable': [], 'remaining': []}
    result: SortedColumns = SortedColumns([], [], [], [])
    if separate_primary_key:
        result.primary_keys = self.get_primary_columns(sort_results=True)
        result.remaining = self.get_secondary_columns(sort_results=True)
    else:
        result.remaining = sorted(self.columns, key=lambda x: x.name)

    if separate_nullable:
        nullable_columns = [column for column in result.remaining if column.is_nullable]  # already sorted
        non_nullable_columns = [column for column in result.remaining if not column.is_nullable]

        # Combine them with non-nullable first
        result.nullable = nullable_columns
        result.non_nullable = non_nullable_columns
        result.remaining = []

    return result

table_dependencies()

Get the table dependencies (foreign tables) for a table.

Source code in src/supabase_pydantic/db/models.py
def table_dependencies(self) -> set[str]:
    """Get the table dependencies (foreign tables) for a table."""
    return set([fk.foreign_table_name for fk in self.foreign_keys])

Core Models

EnumInfo dataclass

Source code in src/supabase_pydantic/core/models.py
@dataclass
class EnumInfo:
    name: str  # The name of the enum type in the DB
    values: list[str]  # The possible values for the enum
    schema: str = 'public'  # The schema, defaulting to 'public'

    def python_class_name(self) -> str:
        """Converts DB enum name to PascalCase for Python class, prefixed by schema.

        e.g., 'order_status' in 'public' -> 'PublicOrderStatusEnum'
        """
        class_name = ''.join(word.capitalize() for word in self.name.split('_')) + 'Enum'
        return f'{self.schema.capitalize()}{class_name}'

    def python_member_name(self, value: str) -> str:
        """Converts enum value to a valid Python identifier.

        e.g., 'pending_new' -> 'pending_new'
        """
        return value.lower()

python_class_name()

Converts DB enum name to PascalCase for Python class, prefixed by schema.

e.g., 'order_status' in 'public' -> 'PublicOrderStatusEnum'

Source code in src/supabase_pydantic/core/models.py
def python_class_name(self) -> str:
    """Converts DB enum name to PascalCase for Python class, prefixed by schema.

    e.g., 'order_status' in 'public' -> 'PublicOrderStatusEnum'
    """
    class_name = ''.join(word.capitalize() for word in self.name.split('_')) + 'Enum'
    return f'{self.schema.capitalize()}{class_name}'

python_member_name(value)

Converts enum value to a valid Python identifier.

e.g., 'pending_new' -> 'pending_new'

Source code in src/supabase_pydantic/core/models.py
def python_member_name(self, value: str) -> str:
    """Converts enum value to a valid Python identifier.

    e.g., 'pending_new' -> 'pending_new'
    """
    return value.lower()

Writers

Serialization

AsDictParent dataclass

Source code in src/supabase_pydantic/utils/serialization.py
@dataclass
class AsDictParent:
    def as_dict(self) -> dict[str, Any]:
        """Convert the dataclass instance to a dictionary."""
        return asdict(self)

    def __str__(self) -> str:
        return json.dumps(asdict(self), indent=4)

as_dict()

Convert the dataclass instance to a dictionary.

Source code in src/supabase_pydantic/utils/serialization.py
def as_dict(self) -> dict[str, Any]:
    """Convert the dataclass instance to a dictionary."""
    return asdict(self)

CustomJsonEncoder

Bases: JSONEncoder

Custom JSON encoder for encoding decimal and datetime.

Source code in src/supabase_pydantic/utils/serialization.py
class CustomJsonEncoder(json.JSONEncoder):
    """Custom JSON encoder for encoding decimal and datetime."""

    def default(self, o: object) -> Any:
        """Encode decimal and datetime objects."""
        if isinstance(o, decimal.Decimal):
            return str(o)
        elif isinstance(o, datetime | date):
            return o.isoformat()
        return super().default(o)

default(o)

Encode decimal and datetime objects.

Source code in src/supabase_pydantic/utils/serialization.py
def default(self, o: object) -> Any:
    """Encode decimal and datetime objects."""
    if isinstance(o, decimal.Decimal):
        return str(o)
    elif isinstance(o, datetime | date):
        return o.isoformat()
    return super().default(o)