Skip to content

JSON Schema

In AMSDAL simply define your data models using a simple JSON format...

{
    "title": "Person",
    "type": "object",
    "properties": {
        "first_name": {
            "type": "string",
            "default": "John"
        },
        "last_name": {
            "type": "string",
            "default": "Doe"
        }
    },
    "required": []
}
...and AMSDAL automatically generates Python model classes...

class Person(Model):
    schema_type: ClassVar[SchemaTypes] = SchemaTypes.USER
    class_fingerprint: ClassVar[str] = '...'
    first_name: Optional[str] = 'John'
    last_name: Optional[str] = 'Doe'

...and any connection/database schema.

CREATE TABLE Person (
    `partition_key` TEXT NOT NULL,
    `first_name` TEXT DEFAULT 'John',
    `last_name` TEXT DEFAULT 'Doe',
    PRIMARY KEY (partition_key)
)

JSON Schema properties

[required] title : string

A string type that represents the name of your model class (it does not allow special symbols)

Best-practice naming conventions Examples
Start each word with a capital letter. Do not separate words with underscores. This style is called camel case or pascal case. Person , MyModel

[required] type : string

All models inherit from a base model class: object

Models can also inherit from any other model by setting its type to the parent model_name:

{
    "title": "PersonWithNickname",
    "type": "Person",
    "properties": {
        "nickname": {
            "type": "string"
        }
    },
    "required": []
}

[required] properties : dictionary[ string : ClassProperty ]

A key-value object that define the list of properties in the model.

Best-practice naming conventions Examples
Use a lowercase word or words. Separate words with underscores to improve readability. age, full_name, date_of_birthday

The value of property is a JSON object that describes the property, and it's type. The format depends on the type of the property.

Built-in property types

Type Example (required)
string {"type": "string"}
number {"type": "number"}
boolean {"type": "boolean"}
array {"type": "array", "items": {"type": "string"}}
dictionary {"type": "dictionary", "items": {"key": {"type": "string"}, "value": {"type": "string}}}
anything {"type": "anything"}

The entire list of supported built-in types can be found here.

Many-to-one relationship

You can use the type property to create a reference to another model.

{
    "title": "Person",
    "type": "object",
    "properties": {
        "address": {
            "type": "Address"
        }
    },
    "required": []
}

Note, it's not possible to explicitly specify database field name for many-to-one relationships in JSON schema.

Many-to-many relationship

You can use array typed property to create a many-to-many reference to another model.

{
    "title": "Person",
    "type": "object",
    "properties": {
        "addresses": {
            "type": "array",
            "items": {
                "type": "Address"
            }
        }
    },
    "required": []
}

Note, it's not possible to explicitly specify an extra model and table for many-to-many relationships in JSON schema.

[optional] default : anything

A parameter that allows you to specify the default value for model's property.

For example:

{
    "title": "Person",
    "type": "object",
    "properties": {
        "age": {
            "type": "number",
            "default": 18
        }
    },
    "required": []
}

In the example if we create a new instance of Person model without specifying the age property, it will be automatically set to 18.

[optional] title : string

The title parameter represents a readable name of property as text in any format:

{
    "title": "Person",
    "type": "object",
    "properties": {
        "age": {
            "type": "number",
            "title": "Person's age"
        }
    },
    "required": []
}

[optional] options : array

The options parameter provides you ability to specify a list of available values for this property as a basic validation, for example:

{
    "title": "Person",
    "type": "object",
    "properties": {
        "country": {
            "type": "string",
            "options": [
                {
                    "value": "USA",
                    "key": "United States"
                },
                {
                    "value": "UK",
                    "key": "United Kingdom"
                }
            ]
        }
    },
    "required": []
}

In the example above we specified the list of available countries for the country property. If you try to create a new instance of Person model with the country property set to e.g. DE, AMSDAL will throw a validation error. The key is just a label or title for the value.

[required] required : array[string]

The required specifies list of property names that are required in this model.

For example:

{
    "title": "Person",
    "type": "object",
    "properties": {
        "name": {
            "type": "string"
        },
        "age": {
            "type": "number",
            "title": "Person age"
        }
    },
    "required": [
        "name"
    ]
}

In this example, the model Person has two properties, name and age, but only name is required. If you try to create a new instance of Person model without specifying a name, AMSDAL will throw a validation error.

[optional] unique : array[array[string]]

The unique allows you to specify which properties must be unique for this model.

For example:

{
    "title": "Person",
    "type": "object",
    "properties": {
        "email": {
            "type": "string"
        },
        "first_name": {
            "type": "string"
        },
        "last_name": {
            "type": "string"
        }
    },
    "required": [
        "first_name",
        "last_name"
    ],
    "unique": [
        [
            "email"
        ],
        [
            "first_name",
            "last_name"
        ]
    ]
}

Note, unique is a list of lists of property names that provide you the ability to specify composite unique constraints. In the example above we created two unique constraints:

  • the first one based on the single email property
  • the second one is a composite one based on the two properties: first_name and last_name

[optional] index : array[string]

The index allows you to specify which properties should be indexed in the database.

For example:

{
    "title": "Person",
    "type": "object",
    "properties": {
        "email": {
            "type": "string"
        },
        "first_name": {
            "type": "string"
        },
        "last_name": {
            "type": "string"
        }
    },
    "required": [
        "email"
    ],
    "index": [
        "email"
    ]
}

Inline JSON Models (TypeModel)

The meta_class property with value "TypeMeta" allows you to define a model that won't be stored as a separate table in the database, but can be used as a field type in other models.

{
    "title": "Address",
    "type": "object",
    "meta_class": "TypeMeta",
    "properties": {
        "street": {
            "type": "string"
        },
        "city": {
            "type": "string"
        },
        "postal_code": {
            "type": "string"
        }
    },
    "required": ["street", "city"]
}

The AMSDAL will generate the following Python model:

from typing import Optional
from amsdal_models.classes.model import TypeModel


class Address(TypeModel):
    street: str
    city: str
    postal_code: Optional[str] = None

When you use this model as a field type in another model:

{
    "title": "Person",
    "type": "object",
    "properties": {
        "name": {
            "type": "string"
        },
        "home_address": {
            "type": "Address"
        }
    },
    "required": ["name"]
}

The home_address field will be stored in the database as a JSON string that contains the structured Address data. The generated Python model will validate that the JSON structure follows the Address schema definition.

This is particularly useful when you need to store structured data that doesn't warrant its own table but still requires validation and a defined structure.