def __getattr__( self, name ): if name not in self._values and self._is_lazy and \ '_id' in self._data and self._data['_id'] is not None: if name not in self._fields: raise AttributeError # field is being accessed and the object is currently in lazy mode # may need to retrieve rest of document field = self._fields[name] if field.dbField not in self._data: # field not retrieved from database! load whole document. weeee result = connection.getDatabase( )[self._collection].find_one( { '_id': self._data['_id'] } ) if result is None: raise self.DoesNotExist self._fromMongo( result, overwrite=False ) self._is_lazy = False field = self._fields.get( name, None ) if not name in self._values: default = None if field is not None: default = field.getDefault( ) self._values[name] = default value = self._values.get( name ) return value
def __get__( self, instance, owner ): if instance is not None: # Document class being accessed, not an object return self if self.collection is None: database = getDatabase( ) self.collection = database[owner._collection] return QuerySet( owner, self.collection )
def __get__( self, instance, owner ): if instance is not None: # Document class being accessed, not an object return self # this should be fast, it's just a thin wrapper to get a collection? groupName = getattr(owner, 'database_group', 'default') database = getDatabase( groupName ) self.collection = database[owner._collection] return QuerySet( owner, self.collection )
def save(self, forceInsert=False, safe=True): database = getDatabase() collection = database[self._collection] self._resyncFromPython() if "_id" in self._data and self._data["_id"] is None: del self._data["_id"] try: if forceInsert: newId = collection.insert(self._data, safe=safe) else: newId = collection.save(self._data, safe=safe) except pymongo.errors.OperationFailure, err: message = "Could not save document (%s)" if u"duplicate key" in unicode(err): message = u"Tried to save duplicate unique keys (%s)" raise OperationError(message % unicode(err))
def save( self, forceInsert=False, **kwargs ): database = getDatabase( ) collection = database[self._collection] self._resyncFromPython( ) if '_id' in self._data and self._data['_id'] is None: del self._data['_id'] try: if forceInsert: newId = collection.insert( self._data, **kwargs ) else: newId = collection.save( self._data, **kwargs ) except pymongo.errors.OperationFailure, err: message = 'Could not save document (%s)' if u'duplicate key' in unicode(err): message = u'Tried to save duplicate unique keys (%s)' raise OperationError( message % unicode(err) )
def __new__( cls, name, bases, attrs ): if DocumentRegistry.hasDocument( name ): return DocumentRegistry.getDocument( name ) # don't do anything if we're the class that defines the metaclass #metaclass = attrs.get( '__metaclass__' ) superNew = super(DocumentMetaclass, cls).__new__ #if metaclass and issubclass(metaclass, DocumentMetaclass): # return superNew( cls, name, bases, attrs ) fields = {} collection = name.lower() needsPrimaryKey = False primaryKey = None # find all inherited fields and record them for base in bases: if hasattr(base, '_fields'): fields.update( base._fields ) if hasattr(base, '_collection'): collection = base._collection if hasattr(base, '__needs_primary_key__'): needsPrimaryKey = True if not '__internal__' in attrs: attrs['_collection'] = collection # find all fields and add them to our field list for attrName, attrValue in attrs.items( ): if hasattr(attrValue, '__class__') and \ issubclass(attrValue.__class__, BaseField): field = attrValue field.name = attrName if not hasattr(field, 'dbField') or field.dbField is None: field.dbField = attrName fields[attrName] = field del attrs[attrName] for field,value in fields.iteritems( ): if value.primaryKey: assert primaryKey is None, "Can only have one primary key per document" primaryKey = field # add a primary key if none exists and one is required if needsPrimaryKey and primaryKey is None: fields['id'] = ObjectIdField( primaryKey=True, dbField='_id' ) primaryKey = 'id' attrs['_primaryKeyField'] = primaryKey # make sure we have all indexes that are specified if 'meta' in attrs: meta = attrs['meta'] if 'indexes' in meta: indexes = meta['indexes'] _database = getDatabase( ) _collection = _database[collection] for index in indexes: if not isinstance(index, (list,tuple)): index = [index] def indexConverter( fieldName ): if fieldName in fields: return fields[fieldName].optimalIndex( ) return fieldName pyMongoIndexKeys = sortListToPyMongo( index, indexConverter ) _collection.ensure_index( pyMongoIndexKeys ) # add a query set manager if none exists already if 'objects' not in attrs: attrs['objects'] = QuerySetManager( ) # construct the new class attrs['_is_lazy'] = False attrs['_fields'] = fields attrs['_data'] = None attrs['_values'] = None newClass = superNew( cls, name, bases, attrs ) # record the document in the fields for field in newClass._fields.values( ): #field.ownerDocument = newClass field.setOwnerDocument( newClass ) # add DoesNotExist and MultipleObjectsReturned exceptions module = attrs.get('__module__') newClass._addException( 'DoesNotExist', bases, defaultBase=DoesNotExist, module=module ) newClass._addException( 'MultipleObjectsReturned', bases, defaultBase=MultipleObjectsReturned, module=module ) # register the document for name-based reference DocumentRegistry.registerDocument( name, newClass ) return newClass