Skip to content

Simple Fields

String

A string field, for small- to large-sized strings. For large amounts of text, use Text.

from protean import Domain
from protean.fields import String

domain = Domain(__file__, load_toml=False)


@domain.aggregate
class Person:
    name = String(required=True, min_length=2, max_length=50, sanitize=True)

Optional Arguments

  • max_length: The maximum length (in characters) of the field. Defaults to 255.
  • min_length: The minimum length (in characters) of the field. Defaults to 255.
  • sanitize: Optionally turn off HTML sanitization. Default is True.

Text

A large text field, to hold large amounts of text. Text fields do not have size constraints.

from protean import Domain
from protean.fields import String, Text

domain = Domain(__file__, load_toml=False)


@domain.aggregate
class Book:
    title = String(max_length=255)
    content = Text(required=True)

Optional Arguments

  • sanitize: Optionally turn off HTML sanitization. Default is True.

Integer

An integer.

from protean import Domain
from protean.fields import Integer, String

domain = Domain(__file__, load_toml=False)


@domain.aggregate
class Person:
    name = String(max_length=255)
    age = Integer(required=True)

Optional Arguments

  • max_value: The maximum numeric value of the field.
  • min_value: The minimum numeric value of the field.

Float

A floating-point number represented in Python by a float instance.

from protean import Domain
from protean.fields import Float, String

domain = Domain(__file__, load_toml=False)


@domain.aggregate
class Account:
    name = String(max_length=255)
    balance = Float(default=0.0)

Optional Arguments

  • max_value: The maximum numeric value of the field.
  • min_value: The minimum numeric value of the field.

Date

A date, represented in Python by a datetime.date instance.

from datetime import datetime

from protean import Domain
from protean.fields import Date, String

domain = Domain(__file__, load_toml=False)


@domain.aggregate
class Post:
    title = String(max_length=255)
    published_on = Date(default=lambda: datetime.today().date())
In [1]: p = Post(title="It")

In [2]: p.to_dict()
Out[2]: 
{'title': 'It',
 'published_on': '2024-05-09',
 'id': '88a21815-7d9b-4138-9cac-5a06889d4318'}

Protean will intelligently convert a valid date string into a date object, with the help of the venerable dateutil module.

In [1]: post = Post(title='Foo', published_on="2020-01-01")

In [2]: post.to_dict()
Out[2]: 
{'title': 'Foo',
 'published_on': '2020-01-01',
 'id': 'ffcb3b26-71f0-45d0-8ca0-b71a9603f792'}

In [3]: Post(title='Foo', published_on="2019-02-29")
ERROR: Error during initialization: {'published_on': ['"2019-02-29" has an invalid date format.']}
...
ValidationError: {'published_on': ['"2019-02-29" has an invalid date format.']}

DateTime

A date and time, represented in Python by a datetime.datetime instance.

from datetime import datetime, timezone

from protean import Domain
from protean.fields import DateTime, String

domain = Domain(__file__, load_toml=False)


@domain.aggregate
class Post:
    title = String(max_length=255)
    created_at = DateTime(default=lambda: datetime.now(timezone.utc))
In [1]: p = Post(title="It")

In [2]: p.to_dict()
Out[2]: 
{'title': 'It',
 'created_at': '2024-05-09 17:12:11.373300+00:00',
 'id': '3a96e434-06ab-4244-80a8-76edbd621a27'}

Boolean

A True/False field.

from protean import Domain
from protean.fields import Boolean, String

domain = Domain(__file__, load_toml=False)


@domain.aggregate
class User:
    name = String(required=True)
    subscribed = Boolean(default=False)
In [1]: u = User(name="John Doe")

In [2]: u.to_dict()
Out[2]: 
{'name': 'John Doe',
 'subscribed': False,
 'id': '69190dd4-12a6-4666-a799-9409ddab39cd'}

Auto

Automatically-generated unique identifiers.

Auto field values are auto-generated unless explicitly supplied. This is the primary difference between Auto and Identifier fields. Since they are always auto-generated, Auto fields cannot be marked required=True.

Optional Arguments

  • increment: Auto-increment field value. Defaults to False. If set, the value is expected to be generated by the database at the time of persistence.

Note

It is necessary for the underlying persistence store to support this increment feature. You have to set up the database schema accordingly. Cross-check with the specific adapter's documentation and your database to confirm if the database supports this functionality.

  • identity_strategy: The strategy to use to generate an identity value. If not provided, the strategy defined at the domain level is used.

  • identity_function: A function that is used to generate the identity value. If not provided, the function defined at the domain level is used.

  • identity_type: The type of the identity value. If not provided, the type defined at the domain level is used.

The identity params are useful when constructing an entity whose identity schema differs from the default.

By default, all entities and aggregates create an Auto field named id that represents their unique identifier.

from protean import Domain
from protean.fields import String

domain = Domain(__file__, load_toml=False)


@domain.aggregate
class Person:
    name = String(required=True, min_length=2, max_length=50, sanitize=True)
In [1]: declared_fields(Person)
Out[1]: 
{'name': String(required=True, max_length=50, min_length=2),
 'id': Auto(identifier=True)}

In [2]: p = Person(name='John Doe')

In [3]: p.to_dict()
Out[3]:
{'name': 'John Doe',
 'id': '7d32e929-e5c5-4856-a6e7-1ebf12e6259e'}

Identity values are UUIDs by default. You can customize this behavior with identity_strategy and identity_type config attributes.

The Identity section deep dives into identities in Protean.

Identifier

An Identifier. The identity type is String type by default, but can be changed with identity_type configuration attribute for all entities, or can be set per entity with the identity_type parameter.

Optional Arguments

  • identity_type: The type of the identifier field. If not provided, it will be picked from the domain configuration. Defaults to STRING. Raises ValidationError if the provided identity type is not supported.
from protean import Domain
from protean.fields import Boolean, Identifier, String
from protean.utils import IdentityType

domain = Domain(__file__, load_toml=False)

# Customize Identity Strategy and Type and activate
domain.config["IDENTITY_TYPE"] = IdentityType.INTEGER.value
domain.domain_context().push()


@domain.aggregate
class User:
    user_id = Identifier(identifier=True)
    name = String(required=True)
    subscribed = Boolean(default=False)
In [1]: user = User(user_id=1, name="John Doe")

In [2]: user.to_dict()
Out[2]: {'user_id': 1, 'name': 'John Doe', 'subscribed': False}

Refer to Identity section for a deep dive into identities in Protean.