0

Self-referencing Python object MongoDB Schema

What am I trying to achieve?

The program I am trying to create handles data describing categories of grocery products, like: Milk, Beef, Corn, Local Fruits and such. I plan on storing this data in a MongoDB instance, therefore creating a schema would be nice.

The reason for my problem is that categories have subcategories (Dairy: Milk, Cheese, Yogurt; Meat: Beef, Pork; etc.), resulting in recursive objects.

Python Alone

I've looked up on StackOverflow how one should approach such structures in Python.

class Category():
    def _init_(self, name, amount, subcategories = ()):
        self.name = name
        self.amount = amount
        for subcategory in subcategories:
            assert isinstance(subcategory, Category)
        self.subcategories = subcategories

This seems about right...

The Schema part

...But only until I try to tie it into a schema:

class Category(mongoengine.EmbeddedDocument):
    def _init_(self, name, amount, subcategories = ()):
        self.name = name
        self.amount = amount
        for subcategory in subcategories:
            assert isinstance(subcategory, Category)
        self.subcategories = subcategories


    name = mongoengine.StringField(required=True)
    amount = mongoengine.FloatField(required=True)
    subcategories = mongoengine.EmbeddedDocumentListField(Category, default=None)
    meta = {
        'db_alias': 'core',
        'collection': 'category',
        'indexes': [
            'name',
            'amount',
            'subcategories',
        ],
        'ordering': ['-name']
    }

Running this code results in an error:

subbcategories = mongoengine.EmbeddedDocumentListField(Category, default=None) NameError: name 'Category' is not defined

I tried referencing the parent category, instead of embedding child categories:

parent_category = mongoengine.ObjectIdField(Category, default=None)

But I still get exactly the same error message:

parent_category = mongoengine.ObjectIdField(Category, default=None)NameError: name 'Category' is not defined

The Question itself

How should I define a schema for a recursive object like this? Is it possible?

Community
  • 1
  • 1

1 Answers1

1

Could you try use str 'Category' instead of type Category in this line:

subcategories = mongoengine.EmbeddedDocumentListField('Category', default=None)

EmbeddedDocumentListField use EmbeddedDocument to init.

EmbeddedDocument accept str.

Ke Zhang
  • 937
  • 1
  • 10
  • 24