Post has not been registered in the document registry. Importing the document class automatically registers it, has it been imported?
I wrote a model that use manytomany relationships, the code are here: 1 from mongoengine import * 2 3 connect('article') 4 class Tag(Document): 5 tag_name = StringField(max_length=30) 6 posts = ListField(ReferenceField('Post', reverse_delete_rule=CASCADE)) 7 8 class Post(Document): 9 title = StringField(max_length=30) 10 content = StringField(max_length=100) 11 tags = ListField(ReferenceField(Tag, reverse_delete_rule=CASCADE)) 12 comments = ListField()
when I use python shell to import this file, there raises the errors just like the title as, Anyone knows why does this happen. Well, sometimes it happens, sometimes it is OK. Really unstable.
You need to ensure that all your Document models have been imported before you try an load the via a query. Otherwise when run a query that requires a Document and it hasn't been imported and added to the registry it will throw that error as it can't initiate the class.
I don't get this, the error happens when importing models, and it only happens when adding the reverse_delete_rule. Using single quote is OK for unregistered class without reverse_delete_rule. So u mean when adding reverse_delete_rule, it did some queries already ?
No - we keep a registry of document classes and to get in the registry the module needs to be imported. People often trip on this error when splitting their models across files and not importing all of them.
Sounds like you are seeing something different are you having an issue here with circular dependencies? Or can you provide a test case?
14 import pdb; pdb.set_trace() 15 class Country(Document): 16 name = StringField(max_length=50, required=True) 17 continents = ListField(ReferenceField(Continent, reverse_delete_rule=PULL)) 18 geo_center = GeoPointField() 19 capital = ReferenceField('City', reverse_delete_rule=NULLIFY) 20 languages = ListField(ReferenceField('Language', reverse_delete_rule=PULL))
class City(Document): 40 name = StringField(max_length=100, required=True, unique_with="country") 41 country = ReferenceField(Country, reverse_delete_rule=NULLIFY) 42 province = ReferenceField(Province, reverse_delete_rule=NULLIFY) 43 geo_center = GeoPointField()
class Language(Document): 63 name = StringField(max_length=50, required=True) 64 abbr = StringField(max_length=5) 65 representations = DictField()
All these three classes are in the same file. When runserver or shell, it reports
mongoengine.base.NotRegistered: Language has not been registered in the document registry.
Importing the document class automatically registers it, has it
been imported?
Ah ok so theres a race condition here with the registering of reverse delete rules. I'll look into fixing.
In the short term if you move the Language class up to the top then that should fix the error here.
Thanks, (nod)
Well, the problem is wherever I put the classes city or country, there are country field in city pointing to country, and capital field in country pointing to city. Sad situation, :(
Bump. @rozza Is there anything I could do to help this along? I'm pretty good with pymongo and I would love to get a pull request in for this, but I imagine that you know better than I where to start poking around on this one.
Affected.
You can easily reproduce the problem like this:
class ModelOne(mongoengine.Document):
subfield = mongoengine.EmbeddedDocumentField('ModelTwo')
class ModelTwo(mongoengine.EmbeddedDocument):
pass
Simply changing the order of the above classes fixes the issue:
class ModelTwo(mongoengine.EmbeddedDocument):
pass
class ModelOne(mongoengine.Document):
subfield = mongoengine.EmbeddedDocumentField('ModelTwo')
It seems strange that passing a string as a parameter to EmbeddedDocumentField is accepted, because the actual functionality contradicts the need for such a thing.
See here in the Django documentation:
If you need to create a relationship on a model that has not yet been defined, you can use the name of the model, rather than the model object itself:
class Car(models.Model): manufacturer = models.ForeignKey('Manufacturer') # ...
class Manufacturer(models.Model): # ...
The idea is that Django does lazy-loading to deal with things not being imported in the right order. Is there a way that we could implement this in MongoEngine?
Another bump. Running into this issue as well with circular references that have reverse_delete_rules.
Running into this issue as well with circular references that have reverse_delete_rules.