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")
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")