Built-in Types
string¶
The string type is used to store text values.
Example:
{
"title": "StringModel",
"type": "object",
"properties": {
"name": {
"type": "string"
},
"country": {
"type": "string",
"default": "USA"
}
},
"required": []
}
In this example we defined two properties name
and country
, both with string type.
from models.user.string_model import StringModel
instance_1 = StringModel(name="Name 1", country="GB")
instance_2 = StringModel(name="Name 2")
Note
The default value that we pass for country
property is a string value as well.
number¶
The number type is used to store any number values (integers and floats).
Example:
{
"title": "NumberModel",
"type": "object",
"properties": {
"count": {
"type": "number",
"default": 0
},
"temperature": {
"type": "number",
"default": 38.8
}
},
"required": []
}
Here, we defined count
and temperature
properties with number type.
from models.user.number_model import NumberModel
instance = NumberModel(count=10)
instance.temperature = 40.1
Note
The default values for count
and temperature
properties are also specified as numbers.
Note
The number values are always stored as float values in the database. So, it means, when you get the data from the database, you will get a float value even if you stored the integer number.
boolean¶
The boolean type is used to store boolean values.
Example:
{
"title": "BooleanModel",
"type": "object",
"properties": {
"is_active": {
"type": "boolean"
},
"is_superuser": {
"type": "boolean",
"default": false
}
},
"required": []
}
In this example, we defined is_active
and is_superuser
properties with boolean type.
from models.user.boolean_model import BooleanModel
instance = BooleanModel(is_active=True)
print(instance.is_active) # True
print(instance.is_superuser) # False
Note
The default value for is_superuser
property is boolean value as well.
array¶
The array type is used to store an ordered list of values. When you define an array property you also need to define the type of items in the array.
Example:
{
"title": "ArrayModel",
"type": "object",
"properties": {
"tags": {
"type": "array",
"items": {
"type": "string"
}
},
"numbers": {
"type": "array",
"items": {
"type": "number"
}
}
},
"required": []
}
In this example, we defined tags
and numbers
properties with array type.
from models.user.array_model import ArrayModel
instance = ArrayModel(tags=["tag 1", "tag 2"], numbers=[1, 2, 3])
Note
The type of the elements in your array must correspond to the type you specified in the schema.
Complex nested arrays¶
AMSDAL allows for complex nested type definition using array.
Here are several examples:
{
"title": "ArrayNestedModel",
"type": "object",
"properties": {
"nested_items": {
"type": "array",
"items": {
"type": "dictionary",
"items": {
"key": {
"type": "string"
},
"value": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
},
"required": []
}
In the example above, the nested_items
property has a complex nested type. When the model class is generated, this
property will be defined as nested_items: list[dict[str, list[str]]]
.
from models.user.array_nested_model import ArrayNestedModel
instance = ArrayNestedModel(
nested_items=[
{"key 1": ["value 1", "value 2"]},
{"key 2": ["value 3"]}
]
)
Note
You need to make sure the types of your array elements correspond to the type you specified in the schema.
Another example of complex nested type definition:
{
"title": "ArrayNestedModel",
"type": "object",
"properties": {
"nested_items": {
"type": "array",
"items": {
"type": "dictionary",
"items": {
"key": {
"type": "string"
},
"value": {
"type": "array",
"items": {
"type": "dictionary",
"items": {
"key": {
"type": "string"
},
"value": {
"type": "string"
}
}
}
}
}
}
}
},
"required": []
}
In this example, the nested_items
property has complex nested type. When the model class is generated, this
property will be defined as nested_items: list[dict[str, list[dict[str, str]]]]
.
from models.user.array_nested_model import ArrayNestedModel
instance = ArrayNestedModel(
nested_items=[
{"key 1": [{"key 1.1": "value 1.1"}, {"key 1.2": "value 1.2"}]},
{"key 2": [{"key 2.1": "value 2.1"}]}
]
)
Note
You need to make sure the types of your array elements correspond to the type you specified in the schema.
It's also possible to define any other model name as a type of the *array element:
{
"title": "ArrayPersonModel",
"type": "object",
"properties": {
"persons": {
"type": "array",
"items": {
"type": "Person"
}
}
},
"required": []
}
Here, we defined the persons
property that has type array of Person model.
from models.user.people import Person
from models.user.array_person_model import ArrayPersonModel
bob = Person.objects.get(name='Bob').execute()
john = Person.objects.get(name='John').execute()
instance = ArrayPersonModel(
persons=[
bob,
john,
],
)
Warning
Currently, it's not possible to filter by elements for the array type using QuerySet.
dictionary¶
The dictionary type is used to store dictionary (map) of values. When you define a dictionary property you also define the types of the dictionaries keys and values.
Example:
{
"title": "DictionaryModel",
"type": "object",
"properties": {
"data": {
"type": "dictionary",
"items": {
"key": {
"type": "string"
},
"value": {
"type": "number"
}
}
}
},
"required": []
}
In the example above, we defined data
property with dictionary type and specified the string type for key
and number type for value.
from models.user.dictionary_model import DictionaryModel
instance = DictionaryModel(data={"key 1": 10, "key 2": 20})
print(instance.data) # {"key 1": 10, "key 2": 20}
Warning
The dictionary's key type must be immutable type. You cannot define array or dictionary as the key type
Complex nested dictionaries¶
The dictionary type allows for complex nested structures where the value
may be another dictionary or array type
{
"title": "DictionaryNestedModel",
"type": "object",
"properties": {
"data": {
"type": "dictionary",
"items": {
"key": {
"type": "string"
},
"value": {
"type": "dictionary",
"items": {
"key": {
"type": "number"
},
"value": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
},
"required": []
}
In this example, the data
property has dict[str, dict[float, list[str]]]
type
from models.user.dictionary_nested_model import DictionaryNestedModel
instance = DictionaryNestedModel(
data={
"key 1": {
10: ["val 1"],
20: ["val 2", "val 3"]
},
"key 2": {
100: ["val 4"]
}
}
)
AMSDAL also supports any other model as either a key or value type
For example:
{
"title": "DictionaryPersonModel",
"type": "object",
"properties": {
"person_age": {
"type": "dictionary",
"items": {
"key": {
"type": "Person"
},
"value": {
"type": "number"
}
}
}
},
"required": []
}
from models.user.people import Person
from models.user.dictionary_person_model import DictionaryPersonModel
bob = Person.objects.get(name='Bob').execute()
john = Person.objects.get(name='John').execute()
instance = DictionaryPersonModel(
person_age={
bob: 18,
john: 21,
},
)
Warning
Currently, it isn't possible to filter by elements for the dictionary type using QuerySet.
binary¶
The binary type allows to store binary data (bytes).
Example:
{
"title": "BinaryModel",
"type": "object",
"properties": {
"data": {
"type": "binary"
}
},
"required": []
}
from models.user.binary_model import BinaryModel
instance = BinaryModel(data=b'binary data')
Note
JSON does not support binary data, therefore you cannot specify the default value for binary type.
anything¶
The anything type allows to store any structure of data. For example, it can be used when you have the array or dictionary with
elements/values of different types, e.g [10, "value", bool]
.
Example:
{
"title": "AnythingModel",
"type": "object",
"properties": {
"meta": {
"type": "dictionary",
"items": {
"key": {
"type": "string"
},
"value": {
"type": "anything"
}
}
},
"data": {
"type": "anything"
}
},
"required": []
}
In this example we defined two properties: meta
and data
. The meta
property has dictionary type with the
string type for keys and anything type for values. The data
property has anything type.
from models.user.anything_model import AnythingModel
instance = AnythingModel(
meta={
"key 1": 10,
"key 2": "value 1",
"key 3": True
},
data=[100, "value 2", False]
)
Note
anything means any valid python or JSON serializable data.
Warning
Try to avoid to use anything type for your properties, as it does not allow for any validation. So, while it is possible to store any kind of data, you cannot guarantee the quality of the data nor use any kind of filtering by this property in QuerySet.
File¶
The File type is built-in model that extends binary type and provides ability to store files in the database. It has the following properties:
Property name | Type | Description |
---|---|---|
filename | string | The name of file. |
data | binary | The binary data of file. |
size | number | The size of file in bytes. |
mimetype | Custom Property | This is custom readonly property, that is calculated automatically based on the filename. |
Example:
{
"title": "FileModel",
"type": "object",
"properties": {
"data": {
"type": "File"
}
},
"required": []
}
from models.user.file_model import FileModel
from models.core.file import File
instance = FileModel(
data=File(
filename='my_file.txt',
data=b'my binary content',
),
)
Info
The File model's data property stores data as bytes, although, it's possible to use string values as well, in which case it will convert the string data into bytes by encoding it to utf-8.
base64 encoded strings are also supported where a base64 encoded string passed as a value will be decoded and stored the original binary data.
from models.core.file import File
instance = File(
filename='my_file.txt',
data='Y29udGVudA==',
)
print(instance.data) # b'content'
The File provides several useful methods.
from_file¶
File.from_file(file_or_path: Path | BinaryIO) static-method
This provides you ability to create the File instance directly from File object or file path.
from pathlib import Path
from models.core.file import File
# From File object
with open('my-file.txt', 'rb') as f:
instance_from_file = File.from_file(f)
# From file path
file_path: Path = Path('my-file.txt')
instance_from_path = File.from_file(file_path)
Note
The file path should be a pathlib.Path
instance. The file object can be any BinaryIO object.
to_file¶
File.to_file(file_or_path: Path | BinaryIO) instance-method
This method provides ability to save the file to the file system.
from pathlib import Path
from models.core.file import File
stored_file = File.obects.get(filename='my-file.txt').execute()
# To File object
with open('my-file.txt', 'wb') as f:
stored_file.to_file(f)
# to file path
file_path: Path = Path('my-file.txt')
stored_file.to_file(file_path)
Note
This method should be executed on the instance of the File model.
└── 📁 models
└── 📁 my_model
├── 📁 hooks
├── 📄 model.json
└── 📁 fixtures
├── 📄 fixture_example.csv
└── 📄 fixture_example.json