Given the following resources:
import odin
class CalendarEvent(odin.Resource):
name = odin.StringField()
start_date: odin.DateTimeField()
class CalendarEventFrom(odin.AnnotatedResource):
name: str
event_date: datetime.date
event_hour: int
event_minute: int
A mapping can be defined to map from a basic Event
to the EventFrom
:
class CalendarEventToEventFrom(odin.Mapping):
from_resource = CalendarEvent
to_resource = CalendarEventFrom
# Simple mappings (From Field, Transformation, To Field)
mappings = (
odin.define(from_field='start_date', to_field='event_date'),
)
# Mapping to multiple fields
@odin.map_field(to_field=('event_hour', 'event_minute'))
def start_date(self, v):
# Return a tuple that is mapped to fields defined as to_fields
return v.hour, v.minute
When a field name is matched on both resources it will be automatically mapped, for other fields mappings need to be specified along with a transformation method or alternatively a method with a :pymap_field
decorator can be used to handle more complex mappings.
Hint
Both simple mappings and :pymap_field
can accept multiple fields as input and output, although care must be taken to ensure that the transformation method accepts and returns the same number of parameters as is defined in the mapping.
Once a mapping has been defined the :pyResource.convert_to
or :pyMapping.apply
are used to convert between object, in addition :pyMapping.update
can be used to update a existing object:
# Create and instance of a CalendarEvent
>>> event = CalendarEvent(
name='Launch Party',
start_date=datetime.datetime(2014, 01, 11, 22, 30))
# Convert to CalendarEventFrom
>>> event_from = event.convert_to(CalendarEventFrom)
>>> event_from
<CalendarEventFrom: example.resources.CalendarEventFrom resource>
>>> event.to_dict()
{'event_date': datetime.datetime(2014, 01, 11, 22, 30),
'event_hour': 22,
'event_minute': 30,
'name': 'Launch Party'}
# Or use the mapping definition CalendarEventToEventFrom
>>> event_from = CalendarEventToEventFrom.apply(event)
# Or update an an existing resource
event.name = 'Grand Launch Party'
event.update_existing(event_from)
>>> event.to_dict()
{'event_date': datetime.datetime(2014, 01, 11, 22, 30),
'event_hour': 22,
'event_minute': 30,
'name': 'Grand Launch Party'}
# Similarly the mapping definition can also be used
>>> CalendarEventToEventFrom(event).update(event_from)