Fields
Included with Marrow Mongo are field types covering all core types supported by MongoDB. A class model is used to define new field types, with a large amount of functionality provided by the base Field
class itself.
This base class is directly usable where the underlying field type is dynamic or not known prior to access.
The Field
class is a subclass of Marrow Schema's Attribute
and all field instances applicable to a given Document
class or instance are accessible using the ordered dictionary __fields__
.
Name Mapping
In general, basic fields accept one positional parameter: the name of the field to store data against within MongoDB. In the following example any attempt to read or write to the field
attriute of a MyDocument
instance will instead retrieve data from the backing document using the key name
. If no name is specified explicitly the name of the attribute the field is assigned to is used by default. The most frequent use of this is in mapping the _id
field from MongoDB to a less cumbersome property name.
You can also pass this name using the name
keyword argument. This may be required (if overriding the default name) for non-basic field types, and is required for complex types.
Defaults & Values
There are a few attributes of a field that determine what happens when an attempt is made to access a value that currently does not exist in the backing document. If no default is provided and there is no value in the backing store for the field, any attempt to read the value of the field through attribute access will result in an AttributeError
exception.
You are additionally given control over what happens when the default value is assigned to the field or the value is deleted (via del
) from the document.
assign
assign
If a default value is provided, automatically assign it to the backing document when a new instance is constructed.
DefaultFalse
default
default
A single value to store, or a function called to generate a new value on first access (the default) or on instance construction (if assign
is True
).
DefaultNo default.
nullable
nullable
If True
, will store None
. If False
, will store non-None
values, or not store. (The key will be missing from the backing store.)
DefaultFalse
required
required
This field must have a value assigned; None
and an empty string are values.
DefaultFalse
Limiting Choice
choices
choices
Passing either an iterable of values, or a callback producing an iterable of values, as the choices
argument allows you to restrict the acceptable values for the field. If static, this list will be included in the validation document. In this way you can emulate an enum or a set if applied to a field encapsulated in an Array
.
The ability to restrict acceptable values this way is available to all types of field. Some, such as Number
and its more specific subclasses, provide additional methods to restrict allowable values, such as ranges or minimums and maximums.
Field Exclusivity
exclusive
exclusive
Occasionally it may be useful to have two distinct fields where it is acceptable to have a value assigned to only one. We model this dependency through exclusion. By passing a set
of field names as the exclusive
argument you can define the fields that must not be set for the current field to be assignable.
Similar to this example, if you wish to define mutual exclusivity you must define both sides of the limitation. MyDocument
declares that if link
is set, mail
can not be set, and likewise the reverse.
Data Transformation
transformer
transformer
As we rely on Marrow Schema we make use of its transformation and validation APIs (and objects) to allow for customization of both data ingress and egress. By default Marrow Mongo attempts to ensure the value stored behind-the-scenes matches MongoDB and BSON datatype expectations to allow for conversion-free final use.
If one wanted to store Python Decimal
objects within the database and wasn't running the latest MongoDB version which has direct support for this type, you could store them safely as strings. An easy way to accomplish this is to use Marrow Schema's Decimal
transformer.
When attempting to retrieve the value, the string stored in the database will be converted to a Decimal
object automatically. When assigning a Decimal
value to the attribute it will be likewise converted back to a string for storage in MongoDB.
Transformation in Field Subclasses
There is a shortcut for handling transformation (when using the default transfomer) in field subclasses, used extensively by the built-in field types. When subclassing Field
you can simply define a to_native
and/or to_foreign
method.
These methods are passed the document the field is attached to, the name of the field, and the value being read or written. They must return either the same value, or some value after hypothetical transformation. The reason for the seeming duplication of the field information (which would otherwise be accessible via self
) is to allow for the assignment of non-method functions, callable objects, or static methods.
Data Validation
validator
validator
By default no data validation is performed beyond the errors that may be raised during datatype transformation for a given Field
subclass. Any field-level configuration for validation-like features effect the generation of the MongoDB-side validation document. You can make use of custom client-side valiation within your own models by utilizing Marrow Schema validation objects.
This example provides a username-based _id
field.
Projection
project
project
Subclasses of Document
provide a __projection__
attribute containing the default set of fields to project based on field project
predicates. Behaviour is somewhat complex; all fields excluding those marked for exclusion (False
) are projected unless any are marked for explicit inclusion (True
) in which case just those are. Fields whose predicates evaluate to None
(the default) will only be included in the former case.
Read/Write Permissions
read
& write
read
& write
The shortcut methods is_readable(context=None)
and is_writeable(context=None)
are provided to evaluate the read
and write
predicates, which follow a pattern similar to projection. Literal True
and False
are allowed as constants to represent "always" and "never". These may alternatively be callbacks (or callable objects) which optionally take a context argument and return True
or False
, or an iterable of such objects which may also return None
to abstain from voting in the access control list (ACL).
Sorting
sort
sort
Virtually identical to the read
and write
access permissions, the sort
predicate follows the same rules and provides an is_sortable(context=None)
evaluation method.
Last updated