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 isTrue
.
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 isTrue
.
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 toFalse
. 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 toSTRING
. RaisesValidationError
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.