linkey apiacess
linkey apiacess

Reputation: 185

python & mongoengine, How do I map data to datetime?

I am trying to store temporal data in mongodb with the use of mongoengine. As the date of the data is a primary component, I thought it would be best to map the data to the date. However, when creating the document I receive an error that states Argument to MapField constructor must be a valid field.

I thought a datetime field was a valid field type given that DateTimeField exists in mongoengine. And reading further into the mongoengine Mapfield documentation, I have a suspicion that I am using it wrong.

Is it possible to map data to a datetime field for storage in mongoengine?

code

from datetime import datetime
from mongoengine import StringField, MapField, EmbeddedDocument, FloatField, IntField

class PlaySession(EmbeddedDocument):
    hours_played = FloatField(db_field="hoursPlayed")
    enjoyment = IntField(db_field="enjoyment")
    number_of_players = IntField(db_field="playerNum")


class GameDoc(Document):
    game = StringField(db_field="game")
    console = StringField(db_field="console")
    sessions = MapField(datetime, PlaySession, db_field="sessions")

Upvotes: 0

Views: 43

Answers (1)

frisko
frisko

Reputation: 867

DateTimeField is a valid type for storing datetime values, but it's not compatible with MapField as a key type. This is why you're getting that error. You can use any of the following alternative solutions instead:

Solution 1: Use MapField and store datetime objects as strings

class GameDoc(Document):
    game = StringField(db_field="game")
    console = StringField(db_field="console")
    sessions = MapField(StringField(), PlaySession, db_field="sessions")

# Example
game = GameDoc(game="Some Game", console="PS5")
game.sessions[datetime.now().strftime('%Y-%m-%d %H:%M:%S')] = PlaySession(hours_played=3.0, enjoyment=9, number_of_players=4)
game.save()

Solution 2: Use ListField and a new document model that stores both the session and the date

class SessionEntry(EmbeddedDocument):
    session_date = DateTimeField(db_field="sessionDate")
    session_data = PlaySession()

class GameDoc(Document):
    game = StringField(db_field="game")
    console = StringField(db_field="console")
    sessions = ListField(EmbeddedDocumentField(SessionEntry), db_field="sessions")

Upvotes: 1

Related Questions