Beispiel #1
0
	def _do_find( self, **kwargs ):
		if 'sort' not in kwargs:
			sorting = sortListToPyMongo( self.orderBy )
			
			if len(sorting) > 0:
				kwargs['sort'] = sorting
		
		if self.onlyFields is not None:
			kwargs['fields'] = self.onlyFields
		
		search = self._get_query( )
		return self.collection.find( search, **kwargs )
Beispiel #2
0
	def ensure_indexed( self ):
		"""Ensures that the most optimal index for the query so far is actually in the database.
		
		Call this whenever a query is deemed expensive."""
		
		indexKeys = []
		
		indexKeys.extend( self._queryToIndex( self.query.toMongo( self.document ) ) )
		
		indexKeys.extend( sortListToPyMongo( self.orderBy ) )
		
		uniqueKeys = []
		for key in indexKeys:
			if key not in uniqueKeys:
				uniqueKeys.append( key )
		
		self.collection.ensure_index( uniqueKeys )
		
		return self
Beispiel #3
0
	def _do_find( self, **kwargs ):
		if 'sort' not in kwargs:
			sorting = sortListToPyMongo( self.orderBy )
			
			if len(sorting) > 0:
				kwargs['sort'] = sorting
		
		if self._fields is not None:
			kwargs['fields'] = self._fields

		if 'timeout' not in kwargs:
			kwargs['timeout'] = self.timeout

		if 'read_preference' not in kwargs and self.readPref is not None:
			kwargs['read_preference'] = self.readPref
		
		search = self._get_query( )

		if '_types' in search and 'fields' in kwargs and not kwargs['fields'].get( '_types' ) and all(kwargs['fields'].itervalues( )):
			kwargs['fields']['_types'] = True

		return self.collection.find( search, **kwargs )
Beispiel #4
0
	def _do_find( self, **kwargs ):
		if 'sort' not in kwargs:
			sorting = sortListToPyMongo( self.orderBy )

			if len(sorting) > 0:
				kwargs['sort'] = sorting

		# fields not supported in pymongo 3.0+, use projection instead
		if 'fields' in kwargs:
			kwargs['projection'] = kwargs['fields']
			del kwargs['fields']
		elif self._fields is not None:
			kwargs['projection'] = self._fields

		# timeout not supported in pymongo 3.0+, use no_cursor_timeout instead
		if 'timeout' in kwargs:
			kwargs['no_cursor_timeout'] = not kwargs['timeout']
		else:
			kwargs['no_cursor_timeout'] = not self.timeout

		search = self._get_query( )

		if '_types' in search and 'projection' in kwargs and not kwargs['projection'].get( '_types' ) and all(kwargs['projection'].itervalues( )):
			kwargs['projection']['_types'] = True

		# read_preference not supported in pymongo 3.0+, use with_options() instead
		if 'read_preference' in kwargs:
			read_preference = kwargs['read_preference']
			del kwargs['read_preference']
		else:
			read_preference = self.readPref

		if read_preference:
			collection = self.collection.with_options(read_preference=read_preference)
		else:
			collection = self.collection

		return collection.find( search, **kwargs )
	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]

		def indexConverter( fieldName ):
			if fieldName in fields:
				return fields[fieldName].optimalIndex( )
			return fieldName

		for field,value in fields.iteritems( ):
			if value.primaryKey:
				assert primaryKey is None, "Can only have one primary key per document"
				primaryKey = field
			if value.unique:
				keyOpts = { 'unique': True }
				
				if value.dropDups:
					keyOpts['dropDups'] = True
				
				connection.stagedIndexes.append( (collection, indexConverter( field ), keyOpts) )
		
		# 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']
				
				for index in indexes:
					if not isinstance(index, (list,tuple)):
						index = [index]
					
					pyMongoIndexKeys = sortListToPyMongo( index, indexConverter )
					connection.stagedIndexes.append( (collection, 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 )

		if connection.database is not None:
			connection.ensureIndexes()
		
		return newClass