Added connect(), document data now stored as Python

Added document length, contains, etc with tests
This commit is contained in:
Harry Marr 2009-11-17 12:03:09 +00:00
parent 0bb0ec0114
commit 688fd5af66
3 changed files with 59 additions and 11 deletions

View File

@ -3,7 +3,38 @@ from document import *
import fields
from fields import *
__all__ = document.__all__ + fields.__all__
from pymongo import Connection
__all__ = document.__all__ + fields.__all__ + ['connect']
__author__ = 'Harry Marr'
__version__ = '0.1'
_connection_settings = {
'host': 'localhost',
'port': 27017,
'pool_size': 1,
}
_connection = None
_db = None
def _get_connection():
if _connection is None:
_connection = Connection(**_connection_settings)
return _connection
def connect(db=None, username=None, password=None, **kwargs):
"""Connect to the database specified by the 'db' argument. Connection
settings may be provided here as well if the database is not running on
the default port on localhost. If authentication is needed, provide
username and password arguments as well.
"""
if db is None:
raise TypeError('"db" argument must be provided to connect()')
_connection_settings.update(kwargs)
connection = _get_connection()
# Get DB from connection and auth if necessary
_db = connection[db]
if username is not None and password is not None:
_db.authenticate(username, password)

View File

@ -24,12 +24,13 @@ class BaseField(object):
# Get value from document instance if available, if not use default
value = instance._data.get(self.name)
if value is not None:
value = self._to_python(value)
elif self.default is not None:
value = self.default
if callable(value):
value = value()
if value is None:
if self.default is not None:
value = self.default
if callable(value):
value = value()
else:
raise AttributeError(self.name)
return value
def __set__(self, instance, value):
@ -40,7 +41,6 @@ class BaseField(object):
try:
value = self._to_python(value)
self._validate(value)
value = self._to_mongo(value)
except ValueError:
raise ValidationError('Invalid value for field of type "' +
self.__class__.__name__ + '"')
@ -61,7 +61,7 @@ class BaseField(object):
def _validate(self, value):
"""Perform validation on a value.
"""
return value
pass
class DocumentMetaclass(type):
@ -143,7 +143,7 @@ class BaseDocument(object):
if attr_value.required:
raise ValidationError('Field "%s" is required' % self.name)
# Use default value
setattr(self, attr_name, getattr(self, attr_name))
setattr(self, attr_name, getattr(self, attr_name, None))
def __iter__(self):
# Use _data rather than _fields as iterator only looks at names so
@ -161,11 +161,21 @@ class BaseDocument(object):
def __setitem__(self, name, value):
"""Dictionary-style field access, set a field's value.
"""
# Ensure that the field exists before settings its value
# Ensure that the field exists before settings its value
if name not in self._fields:
raise KeyError(name)
return setattr(self, name, value)
def __contains__(self, name):
try:
getattr(self, name)
return True
except AttributeError:
return False
def __len__(self):
return len(self._data)
def _to_mongo(self):
"""Return data dictionary ready for use with MongoDB.
"""

View File

@ -61,6 +61,13 @@ class DocumentTest(unittest.TestCase):
person['name'] = 'Another User'
self.assertEquals(person['name'], 'Another User')
self.assertEquals(len(person), 2)
self.assertTrue('age' in person)
person.age = None
self.assertFalse('age' in person)
self.assertFalse('nationality' in person)
def test_embedded_document(self):
"""Ensure that embedded documents are set up correctly.
"""