0

I'm having some trouble getting relationships fields to work in umongo. Each Document definition is in a separate file. In this example i have two basic entities, account and target. each target has a reference to an account.

// account/schema.py

from datetime import datetime
from pymongo import MongoClient
from umongo import Instance, Document, fields, validate
import os
log = Config.config_logger(__name__)

mongo_url = os.environ.get('MONGO_URL')

db = MongoClient(mongo_url).mydb
instance = Instance(db)

@instance.register
class AccountSchema(Document):
    user_id = fields.StringField(required=True, unique=True)
    user_name = fields.StringField(required=True)
    account_type = fields.StringField(required=True)

    class Meta:
        collection = db.account

# Make sure that unique indexes are created
AccountSchema.ensure_indexes()

try:
    sub = AccountSchema(user_id='my8htwwi', account_type='SUBSCRIPTION', user_name='myuser')
    sub.commit()
    freeloader = AccountSchema(user_id='ouygouyg', account_type='FREE', user_name='myotheruser')
    freeloader.commit()
except Exception:
    log.info('account already created')

I've added some manual data there at the bottom, and that works fine when I execute this file, or import it elsewhere.

I define second entity schema for 'target'

// target/schema.py

from datetime import datetime
from pymongo import MongoClient
from umongo import Instance, Document, fields, validate
import os

mongo_url = os.environ.get('MONGO_URL')

db = MongoClient(mongo_url).mydb
instance = Instance(db)


@instance.register
class TargetSchema(Document):
    account = fields.ReferenceField('AccountSchema', required=True)
    date = fields.DateTimeField(
        default=lambda: datetime.utcnow(),
        allow_none=False
    )
    somefield = fields.IntegerField(required=True)
    value = fields.IntegerField(required=True)

    class Meta:
        collection = db.target


# Make sure that unique indexes are created
TargetSchema.ensure_indexes()

service.py

     from models.account.schema import AccountSchema
     from models.target.schema import TargetSchema

     class Service:
       self._odm = TargetSchema

       ....    

       def save_test(data):
         account = AccountRepo().find({'user_id': self._user_id})
         # account returns a valid object  

        item = self._odm(
            account=account,
            somefield=123123,
            value=1234
         )
        return item.commit()

When I call save_test method, I keep keep getting:

umongo.exceptions.NotRegisteredDocumentError: Unknown document class `AccountSchema`

I get the same error if i try and pass the class object AccountSchema in instead

from models.account.schema import AccountSchema

@instance.register
class TargetSchema(Document):
    account = fields.ReferenceField(AccountSchema, required=True)

my feeling is it's about the order that I instantiate/import the instances, but trying to move them around, for example into __init__.py, doesn't seem to change anything.

Or how in each schema definition:


db = MongoClient(mongo_url).target
instance = Instance(db)

All examples I've been able to find keep the referencefield class definition in the same file, so I'm not really sure how to make the different registered instances 'aware' of each other.

baku
  • 765
  • 8
  • 22

1 Answers1

0

so the issue was not declaring and registering all classes to the same db instance.

i.e. in the __init__.py for the models folder i moved:

from umongo import Instance, Document, fields, validate
from pymongo import MongoClient
db = MongoClient(mongo_url).mydb
instance = Instance(db)

then in each schema file:

from models import db
from models import instance
baku
  • 765
  • 8
  • 22