In one MongoEngine model I'm using a reference field, when I use
schedule = ReferenceField('Schedule',required=True)
and attempt to insert the document
#my_schedule being a 'Schedule' object that has been created and saved successfully
record.schedule = my_schedule
record.save()
I get
ValidationError: ValidationError (Calling:None) (A ReferenceField only accepts DBRef or documents: ['schedule'])
However if I change the field definition to
schedule = ReferenceField(path.to.Schedule,required=True)
(I.E. directly reference the Schedule model)
The document can be saved successfully. How can I avoid this error?
Full defenition of the Schedule model
class Schedule(Document):
uid = StringField(required=True)
start = DateTimeField(required=True)
end = DateTimeField(required=True)
days = ListField(required=True)
toc = StringField(required=False)
meta = {
'indexes':['uid']
}
And for Calling
class Calling(Document):
"""
Calling Point
"""
schedule = ReferenceField('Schedule',required=True)
tiploc = StringField(required=True)
calling = ListField(StringField(required=True))
arrive = IntField(required=False)
depart = IntField(required=False)
meta = {
'indexes':[('schedule','calling','tiploc','depart'),('schedule','tiploc')]
}
Python 2.7, MongoEngine 0.8.2, PyMongo 2.5.2
As requested; Output of _document_registry
{'Calling': <class 'models.calling.Calling'>,
'Schedule': <class 'models.schedule.Schedule'>,
'Station': <class 'models.station.Station'>,
'Stop': <class 'models.stop.Stop'>,
'Train': <class 'models.train.Train'>,
'Update': <class 'models.update.Update'>}
Folder layout;
├── app
│ ├── controllers
│ ├── models
│ └── views
└── tasks
app/models controls all my models, this particular error is happening in tasks/update.py (imports a data file into Mongo, run as a cron-job). app/ is appended to the system path when the app loads, if that makes a difference.
in app/models I have one file per model, so app/models/schedule.py contains Schedule etc.
And yes, you are correct in that I have solved the problem by referencing the object directly, however doing that creates a circular dependency problem between calling.py and schedule.py, while I could move Calling and Schedule models to the same file I don't want to because I'm a stubborn programmer and like my one-model-per-file rule despite it making no real difference =)
Adding
print type(my_schedule), schd, type(Schedule)
gives me
<class 'app.models.schedule.Schedule'> Schedule object <class 'mongoengine.base.metaclasses.TopLevelDocumentMetaclass'>
MongoEngine defines a Document class. This is a base class whose inherited class is used to define structure and properties of collection of documents stored in MongoDB database. Each object of this subclass forms Document in Collection in database.
MongoEngine provides the following methods for atomic updates on a queryset. update_one() − Overwrites or adds first document matched by query. update() − Performs atomic update on fields matched by query. modify() − Update a document and return it.
MongoEngine is a library that lets you connect to a MongoDB database and use documents as if they were objects in your code. They dub themselves an ODM (Object-Document Mapper). The project's goal is to create a library similar to other ORM (Object-Relational Mapping) libraries, but for MongoDB.
The definitions look fine, I have a feeling its an import error being masked by the validation error message.
When using Calling
you have to have imported Schedule
somewhere in your code, so that it exists in the document class repository at the time. Does tasks/update.py import both Calling and Schedule models?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With