class Allele(EmbeddedDocument): _id = ObjectIdField() samples = ListField(EmbeddedDocumentField(SampleAllele), default=[]) alt = StringField(required=True) variant_type = ListField(StringField(), default=[]) aa_ref = StringField(required=False) aa_alt = StringField(required=False) aa_pos = IntField(required=False) feature_ref = ObjectIdField(required=False) feature = EmbeddedDocumentField(Feature, required=False)
class UserMenu(Document): # The class that store the relation between the user and the menu, just on special situations id = ObjectIdField() user = LongField(required=True) module = LongField(required=True) created_by = LongField(required=True) created_date = LongField(required=True)
class StructuredQuery(Document): userid = ObjectIdField(required=False) query_object_type = StringField(required=True) query_type = StringField(default='structured', required=False) query = DictField(required=False) creation_time = DateTimeField(default=datetime.now()) query_runtime_duration = FloatField()
class ProductCompanion(Document): # Register all the companions for the product id = ObjectIdField() product = LongField(required=True) companion = LongField(required=True) status = LongField(required=True) created_by = LongField(required=True) created_date = LongField(required=True)
class gardens(Document): name = StringField() address = StringField() topleft_lat = FloatField() topleft_long = FloatField() bottomright_lat = FloatField() bottomright_long = FloatField() plants = ListField(ObjectIdField())
class Buybills_payment(Document): # The Payments of the bills of sale id = ObjectIdField() code = LongField(required=True) total_paid = FloatField(required=True) total_left = FloatField(required=True) pay_date = LongField(required=True) created_by = LongField(required=True) created_date = LongField(required=True)
class recipe_description(Document): # The description, of the content on every recipe id = ObjectIdField() recipe = LongField(required=True) item = LongField(required=True) amount = FloatField(required=True) unit = LongField(required=True) status = LongField(required=True) created_by = LongField(required=True) created_date = LongField(required=True)
class UserInfo(Document): # Another information, that can be store of every User # that handle platea. id = ObjectIdField() client = LongField(required=True) value = StringField(required=True) code = LongField(required=True) created_by = LongField(required=True) created_date = LongField(required=True) meta = {"db_alias": "default"}
class recipe_deduction(Document): # The description of every reduction on the recipe for every sale. id = ObjectIdField() recipe = LongField(required=True) item = LongField(required=True) amount = FloatField(required=True) unit = LongField(required=True) status = LongField(required=True) created_by = LongField(required=True) created_date = LongField(required=True)
class ProductInfo(Document): # All the products to be sell are listed in here. id = ObjectIdField() code = LongField(required=True) price = FloatField(required=True) tax = FloatField(required=True) category = LongField(required=True) status = LongField(required=True) created_by = LongField(required=True) created_date = LongField(required=True)
class SessionUserSys(Document): # The sessions of the user that work with the system. id = ObjectIdField() login = DateTimeField(required=True) logout = DateTimeField(required=True) status = LongField(required=True) created_by = LongField(required=True) created_date = LongField(required=True) code = StringField(required=True, default=CodeGen().GenCode({"table": "SessionUserSys"})) meta = {"db_alias": "default"}
class Variant(Document): organism = StringField(required=True) contig = StringField(required=True) pos = IntField(required=True) gene = StringField(required=False) prot_ref = ObjectIdField() ref = StringField(required=False) sample_alleles = ListField(EmbeddedDocumentField(Allele)) ontologies = ListField(StringField()) search = EmbeddedDocumentField(ProteinDruggabilitySearch, default=None)
class BaseModel(Document): created = DateTimeField(default=datetime.now) modified = DateTimeField(default=datetime.now) created_by = ObjectIdField() modified_by = ObjectIdField() status = IntField(default=Status.VALID) meta = {'abstract': True, 'queryset_class': BaseQuerySetMixin} #=============================================================================== # we can add operate log here too. #=============================================================================== def save(self, *args, **kwargs): try: if not self.created_by: self.created_by = current_user.get_id() self.modified_by = current_user.get_id() except: pass self.modified = datetime.now() Document.save(self, **kwargs) def update(self, *args, **kwargs): try: if not self.created_by: self.created_by = current_user.get_id() self.modified_by = current_user.get_id() except: pass self.modified = datetime.now() return Document.update(self, *args, **kwargs) def delete(self, *args, **kwargs): # we can custom the delete # example: set the status to 0 instead of physical delete return Document.delete(self, *args, **kwargs)
class Metadata(Document): """ Metadata stores information about objects in OmegaStore """ # fields #: this is the name of the data name = StringField(unique_with=['bucket', 'prefix']) #: bucket bucket = StringField() #: prefix prefix = StringField() #: kind of data kind = StringField(choices=MDREGISTRY.KINDS) #: for PANDAS_HDF and SKLEARN_JOBLIB this is the gridfile gridfile = FileField( db_alias='omega', collection_name=settings().OMEGA_MONGO_COLLECTION) #: for PANDAS_DFROWS this is the collection collection = StringField() #: for PYTHON_DATA this is the actual document objid = ObjectIdField() #: omegaml technical attributes, e.g. column indicies kind_meta = DictField() #: customer-defined other meta attributes attributes = DictField() #: s3file attributes s3file = DictField() #: location URI uri = StringField() #: created datetime created = DateTimeField(default=datetime.datetime.now) # the actual db is defined in settings, OMEGA_MONGO_URL meta = { 'db_alias': 'omega', 'indexes': [ # unique entry { 'fields': ['bucket', 'prefix', 'name'], }, 'created', # most recent is last, i.e. [-1] ] } def __eq__(self, other): return self.objid == other.objid def __unicode__(self): fields = ('name', 'bucket', 'prefix', 'created', 'kind') kwargs = ('%s=%s' % (k, getattr(self, k)) for k in self._fields.keys() if k in fields) return u"Metadata(%s)" % ','.join(kwargs)
class SearchQuery(Document): userid = ObjectIdField(required=False) query_object_type = StringField(required=True) query_type = StringField(default='multifield', required=False) # e.g. 15-20, youth raw_strings = StringField() # e.g. # {"field-1":4, # "field-2":5} # where, 4, 5 are the ranking query_fields = DictField(default={}) creation_time = DateTimeField(default=datetime.now()) query_runtime_duration = FloatField()
class Metadata: """ Metadata stores information about objects in OmegaStore """ # NOTE THIS IS ONLY HERE FOR DOCUMENTATION PURPOSE. # # If you use this class to save a document, it will raise a NameError # # The actual Metadata class is created in make_Metadata() below. # Rationale: If we let mongoengine create Metadata here the class # is bound to a specific MongoClient instance. Using make_Metadata # binds the class to the specific instance that exists at the time # of creation. Open to better ways. # fields #: this is the name of the data name = StringField(unique_with=['bucket', 'prefix']) #: bucket bucket = StringField() #: prefix prefix = StringField() #: kind of data kind = StringField(choices=MDREGISTRY.KINDS) #: for PANDAS_HDF and SKLEARN_JOBLIB this is the gridfile gridfile = FileField( db_alias='omega', collection_name=settings().OMEGA_MONGO_COLLECTION) #: for PANDAS_DFROWS this is the collection collection = StringField() #: for PYTHON_DATA this is the actual document objid = ObjectIdField() #: omegaml technical attributes, e.g. column indicies kind_meta = DictField() #: customer-defined other meta attributes attributes = DictField() #: s3file attributes s3file = DictField() #: location URI uri = StringField() #: created datetime created = DateTimeField(default=datetime.datetime.now) #: created datetime modified = DateTimeField(default=datetime.datetime.now)
class ContactHist(Document): # The copy of the contact information # to be easy access on an elastic search id = ObjectIdField() name = StringField(required=True) code = LongField(required=True) created_by = LongField(required=True) telephone = StringField(required=True) contact = LongField(required=True) last_name = StringField() cellphone = StringField() address = StringField() email = StringField() country = LongField() birthdate = LongField() idDocument = StringField() doc_type = StringField() created_date = LongField(required=True) meta = {"db_alias": "default"}
class user_plants(Document): plant_type_id = ObjectIdField() latitude = FloatField() longitude = FloatField() light_duration = FloatField() light_intensity = FloatField() last_watered = DateField() name = StringField() price = FloatField() outdoors = BooleanField() def to_dict(self): return { "_id": str(self.id), "plant_type_id": str(self.plant_type_id), "latitude": self.latitude, "longitude": self.longitude, "light_duration": self.light_duration, "light_intensity": self.light_intensity, "last_watered": self.last_watered, "name": self.name, "price": self.price, "outdoors": self.outdoors }
class LabelValue(Document): id = ObjectIdField() value = StringField(required=True) language = StringField(required=True) #ID of the language label = StringField(required=True)
class Language(Document): id = ObjectIdField() name = StringField(required=True) #The language name code = StringField(required=True) #The language code
class Label(Document): id = ObjectIdField() name = StringField(required=True) #The id on the webpage value = StringField(required=True) #Default value of the label
class Messages(EmbeddedDocument): subject = StringField() createDate = DateTimeField(default=datetime.utcnow()) readFlag = BooleanField(default=False) content = StringField() _id = ObjectIdField(default=ObjectId)
class Metadata(Document): """ Metadata stores information about objects in OmegaStore """ # default kinds of data PANDAS_DFROWS = 'pandas.dfrows' # dataframe PANDAS_SEROWS = 'pandas.serows' # series PANDAS_HDF = 'pandas.hdf' PYTHON_DATA = 'python.data' PANDAS_DFGROUP = 'pandas.dfgroup' SKLEARN_JOBLIB = 'sklearn.joblib' OMEGAML_JOBS = 'script.ipynb' SPARK_MLLIB = 'spark.mllib' OMEGAML_RUNNING_JOBS = 'job.run' #: the list of accepted data types. extend using OmegaStore.register_backend KINDS = [ PANDAS_DFROWS, PANDAS_SEROWS, PANDAS_HDF, PYTHON_DATA, SKLEARN_JOBLIB, PANDAS_DFGROUP, OMEGAML_JOBS, OMEGAML_RUNNING_JOBS, SPARK_MLLIB] # fields #: this is the name of the data name = StringField() #: bucket bucket = StringField() #: prefix prefix = StringField() #: kind of data kind = StringField(choices=KINDS) #: for PANDAS_HDF and SKLEARN_JOBLIB this is the gridfile gridfile = FileField( db_alias='omega', collection_name=settings().OMEGA_MONGO_COLLECTION) #: for PANDAS_DFROWS this is the collection collection = StringField() #: for PYTHON_DATA this is the actual document objid = ObjectIdField() #: omegaml technical attributes, e.g. column indicies kind_meta = DictField() #: customer-defined other meta attributes attributes = DictField() #: s3file attributes s3file = DictField() #: location URI uri = StringField() #: created datetime created = DateTimeField(default=datetime.datetime.now) # the actual db is defined in settings, OMEGA_MONGO_URL meta = { 'db_alias': 'omega', 'indexes': [ # unique entry { 'fields': ['bucket', 'prefix', 'name'], }, 'created', # most recent is last, i.e. [-1] ] } def __unicode__(self): kwargs = ('%s=%s' % (k, getattr(self, k)) for k in self._fields.keys() if k in ('bucket', 'prefix', 'created', 'kind')) return u"Metadata(%s)" % ','.join(kwargs)
class ProductSaleCompanion(Document): # Companion of the Product on the sale id = ObjectIdField() preorder = LongField(required=True) product = LongField(required=True) companion = LongField(required=True)
def __new__(mcs, name, bases, attrs): flattened_bases = mcs._get_bases(bases) super_new = super(TopLevelDocumentMetaclass, mcs).__new__ # Set default _meta data if base class, otherwise get user defined meta if attrs.get("my_metaclass") == TopLevelDocumentMetaclass: # defaults attrs["_meta"] = { "abstract": True, "max_documents": None, "max_size": None, "ordering": [], # default ordering applied at runtime "indexes": [], # indexes to be ensured at runtime "id_field": None, "index_background": False, "index_opts": None, "delete_rules": None, # allow_inheritance can be True, False, and None. True means # "allow inheritance", False means "don't allow inheritance", # None means "do whatever your parent does, or don't allow # inheritance if you're a top-level class". "allow_inheritance": None, } attrs["_is_base_cls"] = True attrs["_meta"].update(attrs.get("meta", {})) else: attrs["_meta"] = attrs.get("meta", {}) # Explicitly set abstract to false unless set attrs["_meta"]["abstract"] = attrs["_meta"].get("abstract", False) attrs["_is_base_cls"] = False # Set flag marking as document class - as opposed to an object mixin attrs["_is_document"] = True # Ensure queryset_class is inherited if "objects" in attrs: manager = attrs["objects"] if hasattr(manager, "queryset_class"): attrs["_meta"]["queryset_class"] = manager.queryset_class # Clean up top level meta if "meta" in attrs: del attrs["meta"] # Find the parent document class parent_doc_cls = [ b for b in flattened_bases if b.__class__ == TopLevelDocumentMetaclass ] parent_doc_cls = None if not parent_doc_cls else parent_doc_cls[0] # Prevent classes setting collection different to their parents # If parent wasn't an abstract class if ( parent_doc_cls and "collection" in attrs.get("_meta", {}) and not parent_doc_cls._meta.get("abstract", True) ): msg = "Trying to set a collection on a subclass (%s)" % name warnings.warn(msg, SyntaxWarning) del attrs["_meta"]["collection"] # Ensure abstract documents have abstract bases if attrs.get("_is_base_cls") or attrs["_meta"].get("abstract"): if parent_doc_cls and not parent_doc_cls._meta.get("abstract", False): msg = "Abstract document cannot have non-abstract base" raise ValueError(msg) return super_new(mcs, name, bases, attrs) # Merge base class metas. # Uses a special MetaDict that handles various merging rules meta = MetaDict() for base in flattened_bases[::-1]: # Add any mixin metadata from plain objects if hasattr(base, "meta"): meta.merge(base.meta) elif hasattr(base, "_meta"): meta.merge(base._meta) # Set collection in the meta if its callable if getattr(base, "_is_document", False) and not base._meta.get("abstract"): collection = meta.get("collection", None) if callable(collection): meta["collection"] = collection(base) meta.merge(attrs.get("_meta", {})) # Top level meta # Only simple classes (i.e. direct subclasses of Document) may set # allow_inheritance to False. If the base Document allows inheritance, # none of its subclasses can override allow_inheritance to False. simple_class = all( [b._meta.get("abstract") for b in flattened_bases if hasattr(b, "_meta")] ) if ( not simple_class and meta["allow_inheritance"] is False and not meta["abstract"] ): raise ValueError( "Only direct subclasses of Document may set " '"allow_inheritance" to False' ) # Set default collection name if "collection" not in meta: meta["collection"] = ( "".join("_%s" % c if c.isupper() else c for c in name) .strip("_") .lower() ) attrs["_meta"] = meta # Call super and get the new class new_class = super_new(mcs, name, bases, attrs) meta = new_class._meta # Set index specifications meta["index_specs"] = new_class._build_index_specs(meta["indexes"]) # If collection is a callable - call it and set the value collection = meta.get("collection") if callable(collection): new_class._meta["collection"] = collection(new_class) # Provide a default queryset unless exists or one has been set if "objects" not in dir(new_class): new_class.objects = QuerySetManager() # Validate the fields and set primary key if needed for field_name, field in iteritems(new_class._fields): if field.primary_key: # Ensure only one primary key is set current_pk = new_class._meta.get("id_field") if current_pk and current_pk != field_name: raise ValueError("Cannot override primary key field") # Set primary key if not current_pk: new_class._meta["id_field"] = field_name new_class.id = field # If the document doesn't explicitly define a primary key field, create # one. Make it an ObjectIdField and give it a non-clashing name ("id" # by default, but can be different if that one's taken). if not new_class._meta.get("id_field"): id_name, id_db_name = mcs.get_auto_id_names(new_class) new_class._meta["id_field"] = id_name new_class._fields[id_name] = ObjectIdField(db_field=id_db_name) new_class._fields[id_name].name = id_name new_class.id = new_class._fields[id_name] new_class._db_field_map[id_name] = id_db_name new_class._reverse_db_field_map[id_db_name] = id_name # Prepend the ID field to _fields_ordered (so that it's *always* # the first field). new_class._fields_ordered = (id_name,) + new_class._fields_ordered # Merge in exceptions with parent hierarchy. exceptions_to_merge = (DoesNotExist, MultipleObjectsReturned) module = attrs.get("__module__") for exc in exceptions_to_merge: name = exc.__name__ parents = tuple( getattr(base, name) for base in flattened_bases if hasattr(base, name) ) or (exc,) # Create a new exception and set it as an attribute on the new # class. exception = type(name, parents, {"__module__": module}) setattr(new_class, name, exception) return new_class
class users(Document): email = StringField() gardens = ListField(ObjectIdField()) unsubscribed = BooleanField()
class ProductPreCompound(Document): # Compounds of the preorder id = ObjectIdField() preorder = LongField(required=True) product = LongField(required=True) compound = LongField(required=True)
# -*- coding: utf-8 -*- from mongoengine.errors import ValidationError from mongoengine.base.fields import ObjectIdField # Used to validate object_ids. # Called by is_valid_object_id OBJECT_ID = ObjectIdField() def is_valid_object_id(value): """Validates BSON IDs using mongoengine's ObjectIdField field.""" try: OBJECT_ID.validate(value) return True except ValidationError: return False def trim_field_key(document, field_key): """ Returns the smallest delimited version of field_key that is an attribute on document. return (key, left_over_array) """ trimming = True left_over_key_values = [] current_key = field_key while trimming and current_key: if hasattr(document, current_key):
def __new__(cls, name, bases, attrs): flattened_bases = cls._get_bases(bases) super_new = super(TopLevelDocumentMetaclass, cls).__new__ # Set default _meta data if base class, otherwise get user defined meta if (attrs.get('my_metaclass') == TopLevelDocumentMetaclass): # defaults attrs['_meta'] = { 'abstract': True, 'max_documents': None, 'max_size': None, 'ordering': [], # default ordering applied at runtime 'indexes': [], # indexes to be ensured at runtime 'id_field': None, 'index_opts': None, 'delete_rules': None, 'allow_inheritance': None, } attrs['_is_base_cls'] = True attrs['_meta'].update(attrs.get('meta', {})) else: attrs['_meta'] = attrs.get('meta', {}) # Explictly set abstract to false unless set attrs['_meta']['abstract'] = attrs['_meta'].get('abstract', False) attrs['_is_base_cls'] = False # Set flag marking as document class - as opposed to an object mixin attrs['_is_document'] = True # Ensure queryset_class is inherited if 'objects' in attrs: manager = attrs['objects'] if hasattr(manager, 'queryset_class'): attrs['_meta']['queryset_class'] = manager.queryset_class # Clean up top level meta if 'meta' in attrs: del(attrs['meta']) # Find the parent document class parent_doc_cls = [b for b in flattened_bases if b.__class__ == TopLevelDocumentMetaclass] parent_doc_cls = None if not parent_doc_cls else parent_doc_cls[0] # Prevent classes setting collection different to their parents # If parent wasn't an abstract class if (parent_doc_cls and 'collection' in attrs.get('_meta', {}) and not parent_doc_cls._meta.get('abstract', True)): msg = "Trying to set a collection on a subclass (%s)" % name warnings.warn(msg, SyntaxWarning) del(attrs['_meta']['collection']) # Ensure abstract documents have abstract bases if attrs.get('_is_base_cls') or attrs['_meta'].get('abstract'): if (parent_doc_cls and not parent_doc_cls._meta.get('abstract', False)): msg = "Abstract document cannot have non-abstract base" raise ValueError(msg) return super_new(cls, name, bases, attrs) # Merge base class metas. # Uses a special MetaDict that handles various merging rules meta = MetaDict() for base in flattened_bases[::-1]: # Add any mixin metadata from plain objects if hasattr(base, 'meta'): meta.merge(base.meta) elif hasattr(base, '_meta'): meta.merge(base._meta) # Set collection in the meta if its callable if (getattr(base, '_is_document', False) and not base._meta.get('abstract')): collection = meta.get('collection', None) if callable(collection): meta['collection'] = collection(base) meta.merge(attrs.get('_meta', {})) # Top level meta # Only simple classes (direct subclasses of Document) # may set allow_inheritance to False simple_class = all([b._meta.get('abstract') for b in flattened_bases if hasattr(b, '_meta')]) if (not simple_class and meta['allow_inheritance'] is False and not meta['abstract']): raise ValueError('Only direct subclasses of Document may set ' '"allow_inheritance" to False') # Set default collection name if 'collection' not in meta: meta['collection'] = ''.join('_%s' % c if c.isupper() else c for c in name).strip('_').lower() attrs['_meta'] = meta # Call super and get the new class new_class = super_new(cls, name, bases, attrs) meta = new_class._meta # Set index specifications meta['index_specs'] = new_class._build_index_specs(meta['indexes']) # If collection is a callable - call it and set the value collection = meta.get('collection') if callable(collection): new_class._meta['collection'] = collection(new_class) # Provide a default queryset unless exists or one has been set if 'objects' not in dir(new_class): new_class.objects = QuerySetManager() # Validate the fields and set primary key if needed for field_name, field in new_class._fields.iteritems(): if field.primary_key: # Ensure only one primary key is set current_pk = new_class._meta.get('id_field') if current_pk and current_pk != field_name: raise ValueError('Cannot override primary key field') # Set primary key if not current_pk: new_class._meta['id_field'] = field_name new_class.id = field # Set primary key if not defined by the document if not new_class._meta.get('id_field'): id_field = ObjectIdField(primary_key=True) id_field.name = 'id' id_field._auto_gen = True new_class._fields['id'] = id_field new_class.id = new_class._fields['id'] new_class._meta['id_field'] = 'id' new_class._db_field_map['id'] = id_field.db_field # Merge in exceptions with parent hierarchy exceptions_to_merge = (DoesNotExist, MultipleObjectsReturned) module = attrs.get('__module__') for exc in exceptions_to_merge: name = exc.__name__ parents = tuple(getattr(base, name) for base in flattened_bases if hasattr(base, name)) or (exc,) # Create new exception and set to new_class exception = type(name, parents, {'__module__': module}) setattr(new_class, name, exception) return new_class
def __new__(mcs, name, bases, attrs): flattened_bases = mcs._get_bases(bases) super_new = super(TopLevelDocumentMetaclass, mcs).__new__ # Set default _meta data if base class, otherwise get user defined meta if attrs.get('my_metaclass') == TopLevelDocumentMetaclass: # defaults attrs['_meta'] = { 'abstract': True, 'max_documents': None, 'max_size': None, 'ordering': [], # default ordering applied at runtime 'indexes': [], # indexes to be ensured at runtime 'id_field': None, 'index_background': False, 'index_drop_dups': False, 'index_opts': None, 'delete_rules': None, # allow_inheritance can be True, False, and None. True means # "allow inheritance", False means "don't allow inheritance", # None means "do whatever your parent does, or don't allow # inheritance if you're a top-level class". 'allow_inheritance': None, } attrs['_is_base_cls'] = True attrs['_meta'].update(attrs.get('meta', {})) else: attrs['_meta'] = attrs.get('meta', {}) # Explicitly set abstract to false unless set attrs['_meta']['abstract'] = attrs['_meta'].get('abstract', False) attrs['_is_base_cls'] = False # Set flag marking as document class - as opposed to an object mixin attrs['_is_document'] = True # Ensure queryset_class is inherited if 'objects' in attrs: manager = attrs['objects'] if hasattr(manager, 'queryset_class'): attrs['_meta']['queryset_class'] = manager.queryset_class # Clean up top level meta if 'meta' in attrs: del attrs['meta'] # Find the parent document class parent_doc_cls = [ b for b in flattened_bases if b.__class__ == TopLevelDocumentMetaclass ] parent_doc_cls = None if not parent_doc_cls else parent_doc_cls[0] # Prevent classes setting collection different to their parents # If parent wasn't an abstract class if (parent_doc_cls and 'collection' in attrs.get('_meta', {}) and not parent_doc_cls._meta.get('abstract', True)): msg = 'Trying to set a collection on a subclass (%s)' % name warnings.warn(msg, SyntaxWarning) del attrs['_meta']['collection'] # Ensure abstract documents have abstract bases if attrs.get('_is_base_cls') or attrs['_meta'].get('abstract'): if (parent_doc_cls and not parent_doc_cls._meta.get('abstract', False)): msg = 'Abstract document cannot have non-abstract base' raise ValueError(msg) return super_new(mcs, name, bases, attrs) # Merge base class metas. # Uses a special MetaDict that handles various merging rules meta = MetaDict() for base in flattened_bases[::-1]: # Add any mixin metadata from plain objects if hasattr(base, 'meta'): meta.merge(base.meta) elif hasattr(base, '_meta'): meta.merge(base._meta) # Set collection in the meta if its callable if (getattr(base, '_is_document', False) and not base._meta.get('abstract')): collection = meta.get('collection', None) if callable(collection): meta['collection'] = collection(base) meta.merge(attrs.get('_meta', {})) # Top level meta # Only simple classes (i.e. direct subclasses of Document) may set # allow_inheritance to False. If the base Document allows inheritance, # none of its subclasses can override allow_inheritance to False. simple_class = all([ b._meta.get('abstract') for b in flattened_bases if hasattr(b, '_meta') ]) if (not simple_class and meta['allow_inheritance'] is False and not meta['abstract']): raise ValueError('Only direct subclasses of Document may set ' '"allow_inheritance" to False') # Set default collection name if 'collection' not in meta: meta['collection'] = ''.join('_%s' % c if c.isupper() else c for c in name).strip('_').lower() attrs['_meta'] = meta # Call super and get the new class new_class = super_new(mcs, name, bases, attrs) meta = new_class._meta # Set index specifications meta['index_specs'] = new_class._build_index_specs(meta['indexes']) # If collection is a callable - call it and set the value collection = meta.get('collection') if callable(collection): new_class._meta['collection'] = collection(new_class) # Provide a default queryset unless exists or one has been set if 'objects' not in dir(new_class): new_class.objects = QuerySetManager() # Validate the fields and set primary key if needed for field_name, field in iteritems(new_class._fields): if field.primary_key: # Ensure only one primary key is set current_pk = new_class._meta.get('id_field') if current_pk and current_pk != field_name: raise ValueError('Cannot override primary key field') # Set primary key if not current_pk: new_class._meta['id_field'] = field_name new_class.id = field # Set primary key if not defined by the document new_class._auto_id_field = getattr(parent_doc_cls, '_auto_id_field', False) if not new_class._meta.get('id_field'): # After 0.10, find not existing names, instead of overwriting id_name, id_db_name = mcs.get_auto_id_names(new_class) new_class._auto_id_field = True new_class._meta['id_field'] = id_name new_class._fields[id_name] = ObjectIdField(db_field=id_db_name) new_class._fields[id_name].name = id_name new_class.id = new_class._fields[id_name] new_class._db_field_map[id_name] = id_db_name new_class._reverse_db_field_map[id_db_name] = id_name # Prepend id field to _fields_ordered new_class._fields_ordered = (id_name, ) + new_class._fields_ordered # Merge in exceptions with parent hierarchy exceptions_to_merge = (DoesNotExist, MultipleObjectsReturned) module = attrs.get('__module__') for exc in exceptions_to_merge: name = exc.__name__ parents = tuple( getattr(base, name) for base in flattened_bases if hasattr(base, name)) or (exc, ) # Create new exception and set to new_class exception = type(name, parents, {'__module__': module}) setattr(new_class, name, exception) return new_class
class ProductSaleCompound(Document): # Compound of products to sale id = ObjectIdField() preorder = LongField(required=True) product = LongField(required=True) compound = LongField(required=True)