1
\$\begingroup\$

I am new in Python, and I am writing a Python class representing a calendar entry, each entry contains 2 properties: the date and its type, which can be weekday/weekend/legal holiday/paid holiday/unpaid holiday. The objects can be serialized into JSON format, saved into a MongoDB collection and loaded back into memory.

The serialization and deserialization are implemented with Marshmallow. The problem is that MongoDB uses field _id as primary key, but I want to make the class property entry_date primary key, so I have to do it manually by adding line: serialized['_id'] = serialized['entry_date'].

Here is the complete source code.

#!/usr/bin/python
# -*- coding: utf-8 -*-

from marshmallow import Schema, fields, post_load
from pymongo import MongoClient
from datetime import date

ENTRY_WEEKDAY = 0
ENTRY_WEEKEND = 1
ENTRY_LEGAL_HOLIDAY = 2
ENTRY_PAID_HOLIDAY = 3
ENTRY_UNPAID_HOLIDAY = 4


class CalendarEntry(object):
    def __init__(self, entry_date, entry_type):
        self.entry_date = entry_date

        iso_format = self.entry_date.isoformat()

        if self.entry_date.weekday() in range(5) and entry_type == ENTRY_WEEKDAY:
            raise ValueError('{0} is already a weekday.'.format(iso_format))
        else:
            if entry_type == ENTRY_WEEKEND:
                raise ValueError('{0} is already a weekend day.'.format(iso_format))
            elif entry_type == ENTRY_UNPAID_HOLIDAY:
                raise ValueError('{0} is a weekend day, cannot be an unpaid holiday.'.format(iso_format))

        self.entry_type = entry_type

    def __getattribute__(self, item):
        if item == 'year':
            return object.__getattribute__(self, 'entry_date').year
        elif item == 'month':
            return object.__getattribute__(self, 'entry_date').month
        elif item == 'day':
            return object.__getattribute__(self, 'entry_date').day
        return object.__getattribute__(self, item)

    def serialize(self):
        schema = CalendarEntrySchema()
        output = schema.dump(self)
        return output.data

    @classmethod
    def make_instance(cls, data):
        schema = CalendarEntrySchema()
        result = schema.load(data)
        return result.data


class CalendarEntrySchema(Schema):
    entry_date = fields.Date(required=True)
    entry_type = fields.Integer(required=True)

    @post_load
    def make_entry(self, data):
        return CalendarEntry(**data)


if __name__ == '__main__':
    entry = CalendarEntry(date(2018, 1, 14), ENTRY_WEEKDAY)
    serialized = entry.serialize()
    print 'Serialized:', serialized

    # Manually add _id field for MongoDB.
    serialized['_id'] = serialized['entry_date']
    print 'Serialized with _id:', serialized

    clnt = MongoClient()
    collection = clnt.hrm.calendar_setting
    result = collection.insert_one(serialized)
    print 'Entry saved, inserted ID:', result.inserted_id

The output:

Serialized: {u'entry_type': 0, u'entry_date': '2018-01-14'}
Serialized with _id: {u'entry_type': 0, '_id': '2018-01-14', u'entry_date': '2018-01-14'}

The code works, but with duplicated fields, _id and entry_date contain exactly the same value.

Any suggestions and critiques please?

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.