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"
    ]
}