Hey
i read here about two way referencing in mongoengine
https://www.mongodb.com/blog/post/6-rules-of-thumb-for-mongodb-schema-design-part-2
how can it be done in mongoengine?
since if i do
class A(Document):
a=ReferenceField(B)
and
class B(Document):
b=ReferenceField(A)
i will get error for circular imports since the module that contains A import B and the module that contains B imports A
b=ReferenceField('A') ?
awesome, thanks my bad
for some reason it does not work with CachedReferenceField
i did
a.py
class A(mongoengine.Document):
aa = mongoengine.StringField()
ab = mongoengine.CachedReferenceField('B', fields=['bb']
b.py
class B(mongoengine.Document):
bb = mongoengine.StringField()
ba = mongoengine.CachedReferenceField('A', fields=['aa']
and when i run a.py i get
mongoengine.NotRegistered: 'A' has not been registered in the document registry. Importing the document class automatically registers it, has it been imported?
@alonstern It's a bad idea to have cross-references.
Generally, a ReferenceField should be used in one way relationships pertaining to a "belongs to" relationship where consistency of data (meaning, keeping the data updated both sides) is important. If consistency is not needed, an EmbeddedDocumentField can be used.
Consider ba field on class B doesn't exist and only class A saves a reference to class B.
Then, in your case,
A and B documents: query A.objectsA documents: query A.objectsB documents: query B.objectsI have the same issue here.
Cross-reference can be useful with Embedded documents.
class WorkSave(me.EmbeddedDocument):
saved_at = me.DateTimeField(default=datetime.datetime.utcnow)
work = me.LazyReferenceField('MyWork', reverse_delete_rule=me.CASCADE)
class MyWork(me.Document):
previous_versions = me.EmbeddedDocumentListField(WorkSave)
In this case, I get mongoengine.errors.NotRegistered: MyWork has not been registered in the document registry.
I can't see any alternative (it used to work at some point though :/ )
Got it!
The problem is due to reverse_delete_rule, that breaks the deferred resolution of the reference. (register_delete_rule calls get_document)
Maybe there should be raise in the constructor to alert developers that both can't work together - or, ideally, a fix that makes it work :)
Thanks.
Most helpful comment
Got it!
The problem is due to
reverse_delete_rule, that breaks the deferred resolution of the reference. (register_delete_rulecallsget_document)Maybe there should be
raisein the constructor to alert developers that both can't work together - or, ideally, a fix that makes it work :)Thanks.