mongoengine icon indicating copy to clipboard operation
mongoengine copied to clipboard

Post has not been registered in the document registry. Importing the document class automatically registers it, has it been imported?

Open xjyjp opened this issue 13 years ago • 11 comments

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.

xjyjp avatar Apr 19 '12 03:04 xjyjp

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.

rozza avatar Apr 24 '12 09:04 rozza

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 ?

PhoenixAndMachine avatar Aug 01 '12 10:08 PhoenixAndMachine

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?

rozza avatar Aug 01 '12 11:08 rozza

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?

PhoenixAndMachine avatar Aug 01 '12 11:08 PhoenixAndMachine

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.

rozza avatar Aug 01 '12 11:08 rozza

Thanks, (nod)

PhoenixAndMachine avatar Aug 01 '12 11:08 PhoenixAndMachine

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, :(

PhoenixAndMachine avatar Aug 01 '12 11:08 PhoenixAndMachine

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.

Slater-Victoroff avatar Sep 01 '13 00:09 Slater-Victoroff

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?

naftulikay avatar Oct 11 '13 01:10 naftulikay

Another bump. Running into this issue as well with circular references that have reverse_delete_rules.

acowlikeobject avatar Oct 15 '13 13:10 acowlikeobject

Running into this issue as well with circular references that have reverse_delete_rules.

arthurmasson avatar Jul 28 '14 09:07 arthurmasson