Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoEngine: A ReferenceField only accepts DBRef or documents when defining document_type as str

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

Update

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

Update 2

Adding

print type(my_schedule), schd, type(Schedule)

gives me

<class 'app.models.schedule.Schedule'> Schedule object <class 'mongoengine.base.metaclasses.TopLevelDocumentMetaclass'>
like image 832
Smudge Avatar asked Jun 09 '13 23:06

Smudge


People also ask

What is document in MongoEngine?

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.

How do I update MongoEngine?

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.

What is Python MongoEngine?

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.


1 Answers

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?

like image 187
Ross Avatar answered Oct 19 '22 13:10

Ross