Skip to content

Fields & Types

Fields are declared as type annotations on a Model, with Field(...) supplying database options (primary key, unique, index, defaults). The lower-level types on this page — FerroField, DbType, and friends — power Annotated[...] declarations and explicit column-type overrides.

Field(default=PydanticUndefined, *, primary_key=_Unset, autoincrement=_Unset, unique=_Unset, index=_Unset, back_ref=_Unset, many_to_many=_Unset, related_name=_Unset, through=_Unset, reverse_index=_Unset, nullable=_Unset, db_type=_Unset, db_check=_Unset, default_factory=_Unset, alias=_Unset, alias_priority=_Unset, validation_alias=_Unset, serialization_alias=_Unset, title=_Unset, field_title_generator=_Unset, description=_Unset, examples=_Unset, exclude=_Unset, exclude_if=_Unset, discriminator=_Unset, deprecated=_Unset, json_schema_extra=_Unset, frozen=_Unset, validate_default=_Unset, repr=_Unset, init=_Unset, init_var=_Unset, kw_only=_Unset, pattern=_Unset, strict=_Unset, coerce_numbers_to_str=_Unset, gt=_Unset, ge=_Unset, lt=_Unset, le=_Unset, multiple_of=_Unset, allow_inf_nan=_Unset, max_digits=_Unset, decimal_places=_Unset, min_length=_Unset, max_length=_Unset, union_mode=_Unset, fail_fast=_Unset, **extra)

Field(default: Literal[Ellipsis], *, primary_key: bool = ..., autoincrement: bool | None = ..., unique: bool = ..., index: bool = ..., back_ref: bool = ..., many_to_many: bool = ..., related_name: str | None = ..., through: str | None = ..., nullable: FerroNullable = ..., db_type: DbType | None = ..., db_check: bool = ..., alias: str | None = ..., alias_priority: int | None = ..., validation_alias: str | AliasPath | AliasChoices | None = ..., serialization_alias: str | None = ..., title: str | None = ..., field_title_generator: Callable[[str, FieldInfo], str] | None = ..., description: str | None = ..., examples: list[Any] | None = ..., exclude: bool | None = ..., exclude_if: Callable[[Any], bool] | None = ..., discriminator: str | types.Discriminator | None = ..., deprecated: Deprecated | str | bool | None = ..., json_schema_extra: JsonDict | Callable[[JsonDict], None] | None = ..., frozen: bool | None = ..., validate_default: bool | None = ..., repr: bool = ..., init: bool | None = ..., init_var: bool | None = ..., kw_only: bool | None = ..., pattern: str | re.Pattern[str] | None = ..., strict: bool | None = ..., coerce_numbers_to_str: bool | None = ..., gt: annotated_types.SupportsGt | None = ..., ge: annotated_types.SupportsGe | None = ..., lt: annotated_types.SupportsLt | None = ..., le: annotated_types.SupportsLe | None = ..., multiple_of: float | None = ..., allow_inf_nan: bool | None = ..., max_digits: int | None = ..., decimal_places: int | None = ..., min_length: int | None = ..., max_length: int | None = ..., union_mode: Literal['smart', 'left_to_right'] = ..., fail_fast: bool | None = ..., **extra: Any) -> Any
Field(default: Any, *, primary_key: bool = ..., autoincrement: bool | None = ..., unique: bool = ..., index: bool = ..., back_ref: bool = ..., many_to_many: bool = ..., related_name: str | None = ..., through: str | None = ..., nullable: FerroNullable = ..., db_type: DbType | None = ..., db_check: bool = ..., alias: str | None = ..., alias_priority: int | None = ..., validation_alias: str | AliasPath | AliasChoices | None = ..., serialization_alias: str | None = ..., title: str | None = ..., field_title_generator: Callable[[str, FieldInfo], str] | None = ..., description: str | None = ..., examples: list[Any] | None = ..., exclude: bool | None = ..., exclude_if: Callable[[Any], bool] | None = ..., discriminator: str | types.Discriminator | None = ..., deprecated: Deprecated | str | bool | None = ..., json_schema_extra: JsonDict | Callable[[JsonDict], None] | None = ..., frozen: bool | None = ..., validate_default: Literal[True], repr: bool = ..., init: bool | None = ..., init_var: bool | None = ..., kw_only: bool | None = ..., pattern: str | re.Pattern[str] | None = ..., strict: bool | None = ..., coerce_numbers_to_str: bool | None = ..., gt: annotated_types.SupportsGt | None = ..., ge: annotated_types.SupportsGe | None = ..., lt: annotated_types.SupportsLt | None = ..., le: annotated_types.SupportsLe | None = ..., multiple_of: float | None = ..., allow_inf_nan: bool | None = ..., max_digits: int | None = ..., decimal_places: int | None = ..., min_length: int | None = ..., max_length: int | None = ..., union_mode: Literal['smart', 'left_to_right'] = ..., fail_fast: bool | None = ..., **extra: Any) -> Any
Field(default: _T, *, primary_key: bool = ..., autoincrement: bool | None = ..., unique: bool = ..., index: bool = ..., back_ref: bool = ..., many_to_many: bool = ..., related_name: str | None = ..., through: str | None = ..., nullable: FerroNullable = ..., db_type: DbType | None = ..., db_check: bool = ..., alias: str | None = ..., alias_priority: int | None = ..., validation_alias: str | AliasPath | AliasChoices | None = ..., serialization_alias: str | None = ..., title: str | None = ..., field_title_generator: Callable[[str, FieldInfo], str] | None = ..., description: str | None = ..., examples: list[Any] | None = ..., exclude: bool | None = ..., exclude_if: Callable[[Any], bool] | None = ..., discriminator: str | types.Discriminator | None = ..., deprecated: Deprecated | str | bool | None = ..., json_schema_extra: JsonDict | Callable[[JsonDict], None] | None = ..., frozen: bool | None = ..., validate_default: Literal[False] = ..., repr: bool = ..., init: bool | None = ..., init_var: bool | None = ..., kw_only: bool | None = ..., pattern: str | re.Pattern[str] | None = ..., strict: bool | None = ..., coerce_numbers_to_str: bool | None = ..., gt: annotated_types.SupportsGt | None = ..., ge: annotated_types.SupportsGe | None = ..., lt: annotated_types.SupportsLt | None = ..., le: annotated_types.SupportsLe | None = ..., multiple_of: float | None = ..., allow_inf_nan: bool | None = ..., max_digits: int | None = ..., decimal_places: int | None = ..., min_length: int | None = ..., max_length: int | None = ..., union_mode: Literal['smart', 'left_to_right'] = ..., fail_fast: bool | None = ..., **extra: Any) -> _T
Field(*, primary_key: bool = ..., autoincrement: bool | None = ..., unique: bool = ..., index: bool = ..., back_ref: bool = ..., many_to_many: bool = ..., related_name: str | None = ..., through: str | None = ..., nullable: FerroNullable = ..., db_type: DbType | None = ..., db_check: bool = ..., default_factory: Callable[[], Any] | Callable[[dict[str, Any]], Any], alias: str | None = ..., alias_priority: int | None = ..., validation_alias: str | AliasPath | AliasChoices | None = ..., serialization_alias: str | None = ..., title: str | None = ..., field_title_generator: Callable[[str, FieldInfo], str] | None = ..., description: str | None = ..., examples: list[Any] | None = ..., exclude: bool | None = ..., exclude_if: Callable[[Any], bool] | None = ..., discriminator: str | types.Discriminator | None = ..., deprecated: Deprecated | str | bool | None = ..., json_schema_extra: JsonDict | Callable[[JsonDict], None] | None = ..., frozen: bool | None = ..., validate_default: Literal[True], repr: bool = ..., init: bool | None = ..., init_var: bool | None = ..., kw_only: bool | None = ..., pattern: str | re.Pattern[str] | None = ..., strict: bool | None = ..., coerce_numbers_to_str: bool | None = ..., gt: annotated_types.SupportsGt | None = ..., ge: annotated_types.SupportsGe | None = ..., lt: annotated_types.SupportsLt | None = ..., le: annotated_types.SupportsLe | None = ..., multiple_of: float | None = ..., allow_inf_nan: bool | None = ..., max_digits: int | None = ..., decimal_places: int | None = ..., min_length: int | None = ..., max_length: int | None = ..., union_mode: Literal['smart', 'left_to_right'] = ..., fail_fast: bool | None = ..., **extra: Any) -> Any
Field(*, primary_key: bool = ..., autoincrement: bool | None = ..., unique: bool = ..., index: bool = ..., back_ref: bool = ..., many_to_many: bool = ..., related_name: str | None = ..., through: str | None = ..., nullable: FerroNullable = ..., db_type: DbType | None = ..., db_check: bool = ..., default_factory: Callable[[], _T] | Callable[[dict[str, Any]], _T], alias: str | None = ..., alias_priority: int | None = ..., validation_alias: str | AliasPath | AliasChoices | None = ..., serialization_alias: str | None = ..., title: str | None = ..., field_title_generator: Callable[[str, FieldInfo], str] | None = ..., description: str | None = ..., examples: list[Any] | None = ..., exclude: bool | None = ..., exclude_if: Callable[[Any], bool] | None = ..., discriminator: str | types.Discriminator | None = ..., deprecated: Deprecated | str | bool | None = ..., json_schema_extra: JsonDict | Callable[[JsonDict], None] | None = ..., frozen: bool | None = ..., validate_default: Literal[False] | None = ..., repr: bool = ..., init: bool | None = ..., init_var: bool | None = ..., kw_only: bool | None = ..., pattern: str | re.Pattern[str] | None = ..., strict: bool | None = ..., coerce_numbers_to_str: bool | None = ..., gt: annotated_types.SupportsGt | None = ..., ge: annotated_types.SupportsGe | None = ..., lt: annotated_types.SupportsLt | None = ..., le: annotated_types.SupportsLe | None = ..., multiple_of: float | None = ..., allow_inf_nan: bool | None = ..., max_digits: int | None = ..., decimal_places: int | None = ..., min_length: int | None = ..., max_length: int | None = ..., union_mode: Literal['smart', 'left_to_right'] = ..., fail_fast: bool | None = ..., **extra: Any) -> _T
Field(*, primary_key: bool = ..., autoincrement: bool | None = ..., unique: bool = ..., index: bool = ..., back_ref: bool = ..., many_to_many: bool = ..., related_name: str | None = ..., through: str | None = ..., nullable: FerroNullable = ..., db_type: DbType | None = ..., db_check: bool = ..., alias: str | None = ..., alias_priority: int | None = ..., validation_alias: str | AliasPath | AliasChoices | None = ..., serialization_alias: str | None = ..., title: str | None = ..., field_title_generator: Callable[[str, FieldInfo], str] | None = ..., description: str | None = ..., examples: list[Any] | None = ..., exclude: bool | None = ..., exclude_if: Callable[[Any], bool] | None = ..., discriminator: str | types.Discriminator | None = ..., deprecated: Deprecated | str | bool | None = ..., json_schema_extra: JsonDict | Callable[[JsonDict], None] | None = ..., frozen: bool | None = ..., validate_default: bool | None = ..., repr: bool = ..., init: bool | None = ..., init_var: bool | None = ..., kw_only: bool | None = ..., pattern: str | re.Pattern[str] | None = ..., strict: bool | None = ..., coerce_numbers_to_str: bool | None = ..., gt: annotated_types.SupportsGt | None = ..., ge: annotated_types.SupportsGe | None = ..., lt: annotated_types.SupportsLt | None = ..., le: annotated_types.SupportsLe | None = ..., multiple_of: float | None = ..., allow_inf_nan: bool | None = ..., max_digits: int | None = ..., decimal_places: int | None = ..., min_length: int | None = ..., max_length: int | None = ..., union_mode: Literal['smart', 'left_to_right'] = ..., fail_fast: bool | None = ..., **extra: Any) -> Any

Build field metadata with Pydantic and Ferro options

Parameters:

Name Type Description Default
default Any

Default value used when the field is not set.

PydanticUndefined
primary_key bool | Any

Mark this column as the table primary key in Ferro.

_Unset
autoincrement bool | None | Any

Override automatic increment behavior for primary key columns. When not provided, Ferro infers this for integer primary keys.

_Unset
unique bool | Any

Add a single-column uniqueness constraint for this column in Ferro. Multi-column uniqueness is declared with __ferro_composite_uniques__ on the model.

_Unset
index bool | Any

Request an index for this column in Ferro.

_Unset
back_ref bool | Any

Mark this field as a reverse relationship. This is the lower-level equivalent of assigning BackRef() as the field default.

_Unset
many_to_many bool | Any

Mark this field as a many-to-many relationship.

_Unset
related_name str | None | Any

Reverse relationship field name used by many-to-many relationships.

_Unset
through str | None | Any

Optional join table name used by many-to-many relationships.

_Unset
nullable FerroNullable | Any

Alembic Column.nullable override for :func:~ferro.migrations.get_metadata. "infer" (default) derives nullability from the field annotation.

_Unset
default_factory Callable[[], Any] | Callable[[dict[str, Any]], Any] | None

A callable to generate the default value. The callable can either take 0 arguments (in which case it is called as is) or a single argument containing the already validated data.

_Unset
alias str | None

The name to use for the attribute when validating or serializing by alias. This is often used for things like converting between snake and camel case.

_Unset
alias_priority int | None

Priority of the alias. This affects whether an alias generator is used.

_Unset
validation_alias str | AliasPath | AliasChoices | None

Like alias, but only affects validation, not serialization.

_Unset
serialization_alias str | None

Like alias, but only affects serialization, not validation.

_Unset
title str | None

Human-readable title.

_Unset
field_title_generator Callable[[str, FieldInfo], str] | None

A callable that takes a field name and returns title for it.

_Unset
description str | None

Human-readable description.

_Unset
examples list[Any] | None

Example values for this field.

_Unset
exclude bool | None

Whether to exclude the field from the model serialization.

_Unset
exclude_if Callable[[Any], bool] | None

A callable that determines whether to exclude a field during serialization based on its value.

_Unset
discriminator str | Discriminator | None

Field name or Discriminator for discriminating the type in a tagged union.

_Unset
deprecated Deprecated | str | bool | None

A deprecation message, an instance of warnings.deprecated or the typing_extensions.deprecated backport, or a boolean. If True, a default deprecation message will be emitted when accessing the field.

_Unset
json_schema_extra JsonDict | Callable[[JsonDict], None] | None

A dict or callable to provide extra JSON schema properties.

_Unset
frozen bool | None

Whether the field is frozen. If true, attempts to change the value on an instance will raise an error.

_Unset
validate_default bool | None

If True, apply validation to the default value every time you create an instance. Otherwise, for performance reasons, the default value of the field is trusted and not validated.

_Unset
repr bool

A boolean indicating whether to include the field in the __repr__ output.

_Unset
init bool | None

Whether the field should be included in the constructor of the dataclass. (Only applies to dataclasses.)

_Unset
init_var bool | None

Whether the field should only be included in the constructor of the dataclass. (Only applies to dataclasses.)

_Unset
kw_only bool | None

Whether the field should be a keyword-only argument in the constructor of the dataclass. (Only applies to dataclasses.)

_Unset
coerce_numbers_to_str bool | None

Whether to enable coercion of any Number type to str (not applicable in strict mode).

_Unset
strict bool | None

If True, strict validation is applied to the field. See Strict Mode for details.

_Unset
gt SupportsGt | None

Greater than. If set, value must be greater than this. Only applicable to numbers.

_Unset
ge SupportsGe | None

Greater than or equal. If set, value must be greater than or equal to this. Only applicable to numbers.

_Unset
lt SupportsLt | None

Less than. If set, value must be less than this. Only applicable to numbers.

_Unset
le SupportsLe | None

Less than or equal. If set, value must be less than or equal to this. Only applicable to numbers.

_Unset
multiple_of float | None

Value must be a multiple of this. Only applicable to numbers.

_Unset
min_length int | None

Minimum length for iterables.

_Unset
max_length int | None

Maximum length for iterables.

_Unset
pattern str | Pattern[str] | None

Pattern for strings (a regular expression).

_Unset
allow_inf_nan bool | None

Allow inf, -inf, nan. Only applicable to float and Decimal numbers.

_Unset
max_digits int | None

Maximum number of allow digits for strings.

_Unset
decimal_places int | None

Maximum number of decimal places allowed for numbers.

_Unset
union_mode Literal['smart', 'left_to_right']

The strategy to apply when validating a union. Can be smart (the default), or left_to_right. See Union Mode for details.

_Unset
fail_fast bool | None

If True, validation will stop on the first error. If False, all validation errors will be collected. This option can be applied only to iterable types (list, tuple, set, and frozenset).

_Unset
extra Unpack[_EmptyKwargs]

(Deprecated) Extra fields that will be included in the JSON schema.

Warning

The extra kwargs is deprecated. Use json_schema_extra instead.

{}

Returns:

Type Description
Any

A new [FieldInfo][pydantic.fields.FieldInfo]. The return annotation is Any so Field can be used on type-annotated fields without causing a type error.

Raises:

Type Description
TypeError

If Ferro kwargs are provided together with callable json_schema_extra.

Examples:

>>> from typing import Annotated
>>> from ferro import Field, Model
>>> class User(Model):
...     id: int | None = Field(default=None, primary_key=True)
...     username: str = Field(unique=True, min_length=3)
>>> class UserAnnotated(Model):
...     id: Annotated[int | None, Field(default=None, primary_key=True)]
...     username: Annotated[str, Field(unique=True, min_length=3)]
Source code in src/ferro/fields.py
def Field(
    default: Any = PydanticUndefined,
    *,
    primary_key: bool | Any = _Unset,
    autoincrement: bool | None | Any = _Unset,
    unique: bool | Any = _Unset,
    index: bool | Any = _Unset,
    back_ref: bool | Any = _Unset,
    many_to_many: bool | Any = _Unset,
    related_name: str | None | Any = _Unset,
    through: str | None | Any = _Unset,
    reverse_index: bool | Any = _Unset,
    nullable: FerroNullable | Any = _Unset,
    db_type: DbType | None | Any = _Unset,
    db_check: bool | Any = _Unset,
    default_factory: Callable[[], Any]
    | Callable[[dict[str, Any]], Any]
    | None = _Unset,
    alias: str | None = _Unset,
    alias_priority: int | None = _Unset,
    validation_alias: str | AliasPath | AliasChoices | None = _Unset,
    serialization_alias: str | None = _Unset,
    title: str | None = _Unset,
    field_title_generator: Callable[[str, FieldInfo], str] | None = _Unset,
    description: str | None = _Unset,
    examples: list[Any] | None = _Unset,
    exclude: bool | None = _Unset,
    exclude_if: Callable[[Any], bool] | None = _Unset,
    discriminator: str | types.Discriminator | None = _Unset,
    deprecated: Deprecated | str | bool | None = _Unset,
    json_schema_extra: JsonDict | Callable[[JsonDict], None] | None = _Unset,
    frozen: bool | None = _Unset,
    validate_default: bool | None = _Unset,
    repr: bool = _Unset,
    init: bool | None = _Unset,
    init_var: bool | None = _Unset,
    kw_only: bool | None = _Unset,
    pattern: str | re.Pattern[str] | None = _Unset,
    strict: bool | None = _Unset,
    coerce_numbers_to_str: bool | None = _Unset,
    gt: annotated_types.SupportsGt | None = _Unset,
    ge: annotated_types.SupportsGe | None = _Unset,
    lt: annotated_types.SupportsLt | None = _Unset,
    le: annotated_types.SupportsLe | None = _Unset,
    multiple_of: float | None = _Unset,
    allow_inf_nan: bool | None = _Unset,
    max_digits: int | None = _Unset,
    decimal_places: int | None = _Unset,
    min_length: int | None = _Unset,
    max_length: int | None = _Unset,
    union_mode: Literal["smart", "left_to_right"] = _Unset,
    fail_fast: bool | None = _Unset,
    **extra: Unpack[_EmptyKwargs],
) -> Any:
    """Build field metadata with Pydantic and Ferro options

    Args:
        default: Default value used when the field is not set.
        primary_key: Mark this column as the table primary key in Ferro.
        autoincrement: Override automatic increment behavior for primary key columns.
            When not provided, Ferro infers this for integer primary keys.
        unique: Add a **single-column** uniqueness constraint for this column in Ferro.
            Multi-column uniqueness is declared with ``__ferro_composite_uniques__`` on the model.
        index: Request an index for this column in Ferro.
        back_ref: Mark this field as a reverse relationship. This is the lower-level
            equivalent of assigning ``BackRef()`` as the field default.
        many_to_many: Mark this field as a many-to-many relationship.
        related_name: Reverse relationship field name used by many-to-many relationships.
        through: Optional join table name used by many-to-many relationships.
        nullable: Alembic ``Column.nullable`` override for :func:`~ferro.migrations.get_metadata`.
            ``\"infer\"`` (default) derives nullability from the field annotation.
        default_factory: A callable to generate the default value. The callable can either take 0 arguments
            (in which case it is called as is) or a single argument containing the already validated data.
        alias: The name to use for the attribute when validating or serializing by alias.
            This is often used for things like converting between snake and camel case.
        alias_priority: Priority of the alias. This affects whether an alias generator is used.
        validation_alias: Like `alias`, but only affects validation, not serialization.
        serialization_alias: Like `alias`, but only affects serialization, not validation.
        title: Human-readable title.
        field_title_generator: A callable that takes a field name and returns title for it.
        description: Human-readable description.
        examples: Example values for this field.
        exclude: Whether to exclude the field from the model serialization.
        exclude_if: A callable that determines whether to exclude a field during serialization based on its value.
        discriminator: Field name or Discriminator for discriminating the type in a tagged union.
        deprecated: A deprecation message, an instance of `warnings.deprecated` or the `typing_extensions.deprecated` backport,
            or a boolean. If `True`, a default deprecation message will be emitted when accessing the field.
        json_schema_extra: A dict or callable to provide extra JSON schema properties.
        frozen: Whether the field is frozen. If true, attempts to change the value on an instance will raise an error.
        validate_default: If `True`, apply validation to the default value every time you create an instance.
            Otherwise, for performance reasons, the default value of the field is trusted and not validated.
        repr: A boolean indicating whether to include the field in the `__repr__` output.
        init: Whether the field should be included in the constructor of the dataclass.
            (Only applies to dataclasses.)
        init_var: Whether the field should _only_ be included in the constructor of the dataclass.
            (Only applies to dataclasses.)
        kw_only: Whether the field should be a keyword-only argument in the constructor of the dataclass.
            (Only applies to dataclasses.)
        coerce_numbers_to_str: Whether to enable coercion of any `Number` type to `str` (not applicable in `strict` mode).
        strict: If `True`, strict validation is applied to the field.
            See [Strict Mode](../concepts/strict_mode.md) for details.
        gt: Greater than. If set, value must be greater than this. Only applicable to numbers.
        ge: Greater than or equal. If set, value must be greater than or equal to this. Only applicable to numbers.
        lt: Less than. If set, value must be less than this. Only applicable to numbers.
        le: Less than or equal. If set, value must be less than or equal to this. Only applicable to numbers.
        multiple_of: Value must be a multiple of this. Only applicable to numbers.
        min_length: Minimum length for iterables.
        max_length: Maximum length for iterables.
        pattern: Pattern for strings (a regular expression).
        allow_inf_nan: Allow `inf`, `-inf`, `nan`. Only applicable to float and [`Decimal`][decimal.Decimal] numbers.
        max_digits: Maximum number of allow digits for strings.
        decimal_places: Maximum number of decimal places allowed for numbers.
        union_mode: The strategy to apply when validating a union. Can be `smart` (the default), or `left_to_right`.
            See [Union Mode](../concepts/unions.md#union-modes) for details.
        fail_fast: If `True`, validation will stop on the first error. If `False`, all validation errors will be collected.
            This option can be applied only to iterable types (list, tuple, set, and frozenset).
        extra: (Deprecated) Extra fields that will be included in the JSON schema.

            !!! warning Deprecated
                The `extra` kwargs is deprecated. Use `json_schema_extra` instead.

    Returns:
        A new [`FieldInfo`][pydantic.fields.FieldInfo]. The return annotation is `Any` so `Field` can be used on
            type-annotated fields without causing a type error.

    Raises:
        TypeError: If Ferro kwargs are provided together with callable `json_schema_extra`.

    Examples:
        >>> from typing import Annotated
        >>> from ferro import Field, Model
        >>> class User(Model):
        ...     id: int | None = Field(default=None, primary_key=True)
        ...     username: str = Field(unique=True, min_length=3)
        >>> class UserAnnotated(Model):
        ...     id: Annotated[int | None, Field(default=None, primary_key=True)]
        ...     username: Annotated[str, Field(unique=True, min_length=3)]
    """
    ferro_kwargs: dict[str, Any] = {}
    if primary_key is not _Unset:
        ferro_kwargs["primary_key"] = primary_key
    if autoincrement is not _Unset:
        ferro_kwargs["autoincrement"] = autoincrement
    if unique is not _Unset:
        ferro_kwargs["unique"] = unique
    if index is not _Unset:
        ferro_kwargs["index"] = index
    if back_ref is not _Unset:
        ferro_kwargs["back_ref"] = back_ref
    if many_to_many is not _Unset:
        ferro_kwargs["many_to_many"] = many_to_many
    if related_name is not _Unset:
        ferro_kwargs["related_name"] = related_name
    if through is not _Unset:
        ferro_kwargs["through"] = through
    if reverse_index is not _Unset:
        ferro_kwargs["reverse_index"] = reverse_index
    if nullable is not _Unset:
        _validate_nullable_option(nullable, "Field")
        ferro_kwargs["nullable"] = nullable
    if db_type is not _Unset:
        ferro_kwargs["db_type"] = db_type
    if db_check is not _Unset:
        ferro_kwargs["db_check"] = db_check

    schema_extra = json_schema_extra
    if ferro_kwargs:
        if callable(schema_extra):
            raise TypeError(
                "ferro.Field(..., primary_key=...) cannot be combined with callable "
                "json_schema_extra"
            )
        base_extra: dict[str, Any]
        if schema_extra is _Unset or schema_extra is None:
            base_extra = {}
        else:
            base_extra = dict(schema_extra)
        merged_extra: dict[str, Any] = base_extra
        merged_extra[FERRO_FIELD_EXTRA_KEY] = ferro_kwargs
        schema_extra = merged_extra

    return PydanticField(
        default=default,
        default_factory=default_factory,
        alias=alias,
        alias_priority=alias_priority,
        validation_alias=validation_alias,
        serialization_alias=serialization_alias,
        title=title,
        field_title_generator=field_title_generator,
        description=description,
        examples=examples,
        exclude=exclude,
        exclude_if=exclude_if,
        discriminator=discriminator,
        deprecated=deprecated,
        json_schema_extra=schema_extra,
        frozen=frozen,
        validate_default=validate_default,
        repr=repr,
        init=init,
        init_var=init_var,
        kw_only=kw_only,
        pattern=pattern,
        strict=strict,
        coerce_numbers_to_str=coerce_numbers_to_str,
        gt=gt,
        ge=ge,
        lt=lt,
        le=le,
        multiple_of=multiple_of,
        allow_inf_nan=allow_inf_nan,
        max_digits=max_digits,
        decimal_places=decimal_places,
        min_length=min_length,
        max_length=max_length,
        union_mode=union_mode,
        fail_fast=fail_fast,
        **extra,
    )

FerroField

Store database column metadata for a model field

Attributes:

primary_key: Mark the field as the table primary key.
autoincrement: Override automatic increment behavior for primary key columns.
unique: Enforce a **single-column** uniqueness constraint for this column only.
    For uniqueness on multiple columns together, declare
    ``__ferro_composite_uniques__`` on the :class:`ferro.models.Model` subclass
    (see the models guide).
index: Request an index for the column.
nullable: Alembic ``Column.nullable`` when using :func:`~ferro.migrations.get_metadata`.
    ``'infer'`` (default) uses whether the annotation allows ``None``.
    ``False`` / ``True`` force NOT NULL / NULL regardless of the type (for
    advanced cases such as ``int | None`` used only for static typing).
db_type: Optional canonical SQL-type override (:data:`DbType`). Use a
    :data:`DbTypeToken` literal or :func:`varchar` for ``varchar(N)``.
    Strict validation against the Python annotation runs at class-definition
    time. Default ``None`` preserves today's behavior.
db_check: When ``True``, emit a DB-side ``CHECK`` constraint enforcing the
    allowed values for closed-domain types (``enum.Enum`` subclasses).
    Only valid in combination with ``db_type``; combining with default
    native-enum storage is rejected as redundant. Default ``False``.

Examples:

>>> from typing import Annotated
>>> from ferro.models import Model
>>>
>>> class User(Model):
...     id: Annotated[int, FerroField(primary_key=True)]
...     email: Annotated[str, FerroField(unique=True, index=True)]
Source code in src/ferro/base.py
class FerroField:
    """Store database column metadata for a model field

    Attributes:

        primary_key: Mark the field as the table primary key.
        autoincrement: Override automatic increment behavior for primary key columns.
        unique: Enforce a **single-column** uniqueness constraint for this column only.
            For uniqueness on multiple columns together, declare
            ``__ferro_composite_uniques__`` on the :class:`ferro.models.Model` subclass
            (see the models guide).
        index: Request an index for the column.
        nullable: Alembic ``Column.nullable`` when using :func:`~ferro.migrations.get_metadata`.
            ``'infer'`` (default) uses whether the annotation allows ``None``.
            ``False`` / ``True`` force NOT NULL / NULL regardless of the type (for
            advanced cases such as ``int | None`` used only for static typing).
        db_type: Optional canonical SQL-type override (:data:`DbType`). Use a
            :data:`DbTypeToken` literal or :func:`varchar` for ``varchar(N)``.
            Strict validation against the Python annotation runs at class-definition
            time. Default ``None`` preserves today's behavior.
        db_check: When ``True``, emit a DB-side ``CHECK`` constraint enforcing the
            allowed values for closed-domain types (``enum.Enum`` subclasses).
            Only valid in combination with ``db_type``; combining with default
            native-enum storage is rejected as redundant. Default ``False``.

    Examples:
        >>> from typing import Annotated
        >>> from ferro.models import Model
        >>>
        >>> class User(Model):
        ...     id: Annotated[int, FerroField(primary_key=True)]
        ...     email: Annotated[str, FerroField(unique=True, index=True)]
    """

    def __init__(
        self,
        primary_key: bool = False,
        autoincrement: bool | None = None,
        unique: bool = False,
        index: bool = False,
        nullable: FerroNullable = "infer",
        db_type: DbType | None = None,
        db_check: bool = False,
    ):
        """Initialize field metadata options

        Args:

            primary_key: Set to True when the field is the primary key.
            autoincrement: Control whether the database auto-increments the value.
                When not provided, the backend infers a default for integer primary keys.
            unique: Set to True to enforce **single-column** uniqueness only.
            index: Set to True to create a database index.
            nullable: See :class:`FerroField` attribute ``nullable`` in the class docstring.

        Examples:
            >>> from typing import Annotated
            >>> from ferro.models import Model
            >>>
            >>> class User(Model):
            ...     id: Annotated[int, FerroField(primary_key=True)]
            ...     created_at: Annotated[int, FerroField(index=True)]
        """
        self.primary_key = primary_key
        self.autoincrement = autoincrement
        self.unique = unique
        self.index = index
        self.nullable = _validate_nullable_option(nullable, "FerroField")
        self.db_type = db_type
        self.db_check = db_check

Attributes

primary_key = primary_key instance-attribute

autoincrement = autoincrement instance-attribute

unique = unique instance-attribute

index = index instance-attribute

nullable = _validate_nullable_option(nullable, 'FerroField') instance-attribute

db_type = db_type instance-attribute

db_check = db_check instance-attribute

Functions

__init__(primary_key=False, autoincrement=None, unique=False, index=False, nullable='infer', db_type=None, db_check=False)

Initialize field metadata options

Args:

primary_key: Set to True when the field is the primary key.
autoincrement: Control whether the database auto-increments the value.
    When not provided, the backend infers a default for integer primary keys.
unique: Set to True to enforce **single-column** uniqueness only.
index: Set to True to create a database index.
nullable: See :class:`FerroField` attribute ``nullable`` in the class docstring.

Examples:

>>> from typing import Annotated
>>> from ferro.models import Model
>>>
>>> class User(Model):
...     id: Annotated[int, FerroField(primary_key=True)]
...     created_at: Annotated[int, FerroField(index=True)]
Source code in src/ferro/base.py
def __init__(
    self,
    primary_key: bool = False,
    autoincrement: bool | None = None,
    unique: bool = False,
    index: bool = False,
    nullable: FerroNullable = "infer",
    db_type: DbType | None = None,
    db_check: bool = False,
):
    """Initialize field metadata options

    Args:

        primary_key: Set to True when the field is the primary key.
        autoincrement: Control whether the database auto-increments the value.
            When not provided, the backend infers a default for integer primary keys.
        unique: Set to True to enforce **single-column** uniqueness only.
        index: Set to True to create a database index.
        nullable: See :class:`FerroField` attribute ``nullable`` in the class docstring.

    Examples:
        >>> from typing import Annotated
        >>> from ferro.models import Model
        >>>
        >>> class User(Model):
        ...     id: Annotated[int, FerroField(primary_key=True)]
        ...     created_at: Annotated[int, FerroField(index=True)]
    """
    self.primary_key = primary_key
    self.autoincrement = autoincrement
    self.unique = unique
    self.index = index
    self.nullable = _validate_nullable_option(nullable, "FerroField")
    self.db_type = db_type
    self.db_check = db_check

FerroNullable = Literal['infer'] | bool module-attribute

Alembic column nullability: 'infer' from the field type, or forced bool.

varchar(length)

Build the canonical varchar(N) token for :func:~ferro.Field db_type=.

Prefer this over a raw string so IDEs and type checkers see a deliberate Ferro vocabulary choice. Runtime validation still applies at model definition time.

Examples:

>>> varchar(255)
'varchar(255)'
Source code in src/ferro/base.py
def varchar(length: int) -> str:
    """Build the canonical ``varchar(N)`` token for :func:`~ferro.Field` ``db_type=``.

    Prefer this over a raw string so IDEs and type checkers see a deliberate
    Ferro vocabulary choice. Runtime validation still applies at model
    definition time.

    Examples:
        >>> varchar(255)
        'varchar(255)'
    """
    if length <= 0:
        raise ValueError(f"varchar length must be positive, got {length}")
    return f"varchar({length})"

DbType = DbTypeToken | str module-attribute

Canonical db_type value: a :data:DbTypeToken or varchar(N) (see :func:varchar).

DbTypeToken = Literal['text', 'smallint', 'int', 'bigint', 'uuid', 'timestamp', 'timestamptz', 'date', 'time'] module-attribute

Fixed canonical SQL storage tokens accepted by :func:~ferro.Field db_type=.