Blank
Blank

Reputation: 4705

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'>

Upvotes: 6

Views: 5593

Answers (1)

Ross
Ross

Reputation: 18111

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?

Upvotes: 1

Related Questions