Field Types¶
Beyond standard Python types (str, int, float, bool, etc.), AMSDAL provides specialized field types for common patterns like file uploads, vector embeddings, and relationships between models.
VectorField¶
VectorField creates a fixed-dimension vector column, useful for storing embeddings from ML models.
from amsdal_models.classes.fields.vector import VectorField
from amsdal.models import Model
class Document(Model):
title: str
embedding: VectorField(768) # 768-dimensional vector
Parameters:
| Parameter | Type | Description |
|---|---|---|
dimensions |
int |
Number of dimensions for the vector |
The field stores a list[float] and includes dimension metadata in the JSON schema for validation.
FileField¶
FileField configures a File-typed field with a specific storage backend.
from amsdal_models.classes.fields.file import FileField
from amsdal.models import Model
from amsdal_models.storage.backends.db import DBStorage
from amsdal.storages.file_system import FileSystemStorage
from amsdal.models.core.file import File
class Attachment(Model):
name: str
# Default storage (from settings)
document: File
# Explicit database storage
avatar: File = FileField(title='Avatar', storage=DBStorage())
# Explicit filesystem storage
report: File = FileField(
title='Report',
storage=FileSystemStorage('/var/media', 'https://cdn.example.com/media/'),
)
# Optional file field
thumbnail: File | None = FileField(default=None, storage=DBStorage())
Parameters:
| Parameter | Type | Description |
|---|---|---|
storage |
Storage \| None |
Storage backend instance. If None, uses the default from settings. |
*args, **kwargs |
Standard Pydantic Field arguments (default, title, description, etc.) |
See File Storage for details on the File model and storage backends.
ReferenceField¶
ReferenceField defines a foreign-key relationship to another model.
from amsdal.models import Model, ReferenceField
from amsdal_models.classes.relationships.enum import ReferenceMode
class Department(Model):
name: str
class Employee(Model):
name: str
department: Department = ReferenceField(..., on_delete=ReferenceMode.CASCADE)
Parameters:
| Parameter | Type | Description |
|---|---|---|
on_delete |
ReferenceMode \| Callable |
Behavior when the referenced object is deleted |
db_field |
str \| list[str] \| Callable |
Database column name(s) for the foreign key. Default: {field_name}_id |
*args, **kwargs |
Standard Pydantic Field arguments |
on_delete options¶
from amsdal_models.classes.relationships.enum import ReferenceMode
| Mode | Description |
|---|---|
CASCADE |
Delete this object when the referenced object is deleted |
PROTECT |
Prevent deletion of the referenced object if references exist |
RESTRICT |
Similar to PROTECT, enforced at database level |
SET_NULL |
Set the foreign key to None (field must be optional) |
SET_DEFAULT |
Set the foreign key to its default value |
DO_NOTHING |
Take no action (may cause integrity errors) |
You can also pass a callable for custom behavior:
def archive_on_delete(referenced_obj):
# Custom cleanup logic
pass
class Employee(Model):
department: Department = ReferenceField(..., on_delete=archive_on_delete)
Custom db_field¶
class Employee(Model):
department: Department = ReferenceField(..., db_field='dept_id', on_delete=ReferenceMode.CASCADE)
Composite foreign keys¶
When the referenced model has a composite primary key, provide a list of column names:
class Asset(Model):
__primary_key__: ClassVar[list[str]] = ['asset_name', 'asset_type']
asset_name: str
asset_type: str
class Person(Model):
asset: Asset = ReferenceField(
...,
db_field=['asset_name', 'asset_type'],
on_delete=ReferenceMode.CASCADE,
)
ManyReferenceField¶
ManyReferenceField defines a many-to-many relationship via a through model.
from amsdal.models import ManyReferenceField
class Tag(Model):
name: str
class PostTag(Model):
post: 'Post' = ReferenceField(..., db_field='post_id', on_delete=ReferenceMode.CASCADE)
tag: Tag = ReferenceField(..., db_field='tag_id', on_delete=ReferenceMode.CASCADE)
class Post(Model):
title: str
tags: list[Tag] = ManyReferenceField(
through=PostTag,
through_fields=('post', 'tag'),
)
Model Meta Options¶
__table_name__¶
Override the default database table name:
from typing import ClassVar
class Person(Model):
__table_name__: ClassVar[str] = 'people'
first_name: str
last_name: str
Without __table_name__, the class name is used as the table name.
__primary_key__¶
Specify custom primary key field(s). By default, AMSDAL adds a partition_key field.
class Person(Model):
__primary_key__: ClassVar[list[str]] = ['person_id']
person_id: int
first_name: str
Composite primary key:
class Enrollment(Model):
__primary_key__: ClassVar[list[str]] = ['student', 'course']
student: 'Student' = ReferenceField(..., on_delete=ReferenceMode.CASCADE)
course: 'Course' = ReferenceField(..., db_field='course_id', on_delete=ReferenceMode.CASCADE)
enrollment_date: date
__constraints__¶
Define unique constraints across one or more fields:
from amsdal.models import UniqueConstraint
class Person(Model):
__constraints__: ClassVar[list[UniqueConstraint]] = [
UniqueConstraint(name='unq_person_email', fields=['email']),
UniqueConstraint(name='unq_person_name', fields=['first_name', 'last_name']),
]
first_name: str
last_name: str
email: str
__indexes__¶
Define database indexes for faster lookups:
from amsdal.models import IndexInfo
class Person(Model):
__indexes__: ClassVar[list[IndexInfo]] = [
IndexInfo(name='idx_person_email', field='email'),
]
email: str
Combining meta options¶
class Course(Model):
__table_name__: ClassVar[str] = 'courses'
__primary_key__: ClassVar[list[str]] = ['course_id']
__indexes__: ClassVar[list[IndexInfo]] = [
IndexInfo(name='idx_course_name', field='course_name'),
]
__constraints__: ClassVar[list[UniqueConstraint]] = [
UniqueConstraint(name='unq_course_name', fields=['course_name']),
]
course_id: int
course_name: str
description: str = ''