class TypesTestCase(unittest.TestCase): def setUp(self): self.connection = Connection() self.col = self.connection['test']['mongokit'] def tearDown(self): self.connection.drop_database('test') def test_authorized_type(self): for auth_type in SchemaDocument.authorized_types: if auth_type is dict: auth_type = {} class MyDoc(SchemaDocument): structure = {"foo": auth_type} if type(auth_type) is dict: assert MyDoc() == {"foo": {}}, MyDoc() elif auth_type is list: assert MyDoc() == {"foo": []} else: assert MyDoc() == {"foo": None}, auth_type def test_not_authorized_type(self): for unauth_type in [set, str]: failed = False try: class MyDoc(SchemaDocument): structure = {"foo": [unauth_type]} except StructureError, e: self.assertEqual( str(e), "MyDoc: %s is not an authorized type" % unauth_type) failed = True self.assertEqual(failed, True) failed = False try: class MyDoc(SchemaDocument): structure = {"foo": (unauth_type)} except StructureError, e: self.assertEqual( str(e), "MyDoc: %s is not an authorized type" % unauth_type) failed = True self.assertEqual(failed, True) failed = False try: class MyDoc2(SchemaDocument): structure = {'foo': [{int: unauth_type}]} except StructureError, e: self.assertEqual( str(e), "MyDoc2: %s is not an authorized type" % unauth_type) failed = True
class TypesTestCase(unittest.TestCase): def setUp(self): self.connection = Connection() self.col = self.connection['test']['mongokit'] def tearDown(self): self.connection.drop_database('test') def test_authorized_type(self): for auth_type in SchemaDocument.authorized_types: if auth_type is dict: auth_type = {} class MyDoc(SchemaDocument): structure = { "foo":auth_type } if type(auth_type) is dict: assert MyDoc() == {"foo":{}}, MyDoc() elif auth_type is list: assert MyDoc() == {"foo":[]} else: assert MyDoc() == {"foo":None}, auth_type def test_not_authorized_type(self): for unauth_type in [set]: failed = False try: class MyDoc(SchemaDocument): structure = { "foo":[unauth_type] } except StructureError, e: self.assertEqual(str(e), "MyDoc: %s is not an authorized type" % unauth_type) failed = True self.assertEqual(failed, True) failed = False try: class MyDoc(SchemaDocument): structure = { "foo":(unauth_type) } except StructureError, e: self.assertEqual(str(e), "MyDoc: %s is not an authorized type" % unauth_type) failed = True self.assertEqual(failed, True) failed = False try: class MyDoc2(SchemaDocument): structure = { 'foo':[{int:unauth_type }]} except StructureError, e: self.assertEqual(str(e), "MyDoc2: %s is not an authorized type" % unauth_type) failed = True
def init_db(host=None, port=None, database=None): con = Connection(host, port) con.drop_database(database) con.register([Admin, AdminRole]) db = Database(con, database) generate_index(host, port, database) role = db.AdminRole() role['name'] = u'管理员' role['auth_list'] = get_auth_list() role.save() user = db.Admin() user['email'] = u'*****@*****.**' user['name'] = u'admin' user['password'] = db.Admin.encode_pwd('123456') user['login_time'] = datetime.now() user['status'] = True user['role'] = role user.save() return 'success'
DBSession.images.insert(tempImage) def saveVMTypes(vmTypes): for vmType in vmTypes['types']: DBSession.vmtypes.insert(vmType) def installPackage(package): easy_install.main(["-U", package]) def copyImagesToServer(): images = DBSession.images.find() for image in images: location = image['location'] fileName = "../src/images/" + image['name'] + "__" + str(image['_id']) system('scp "%s" "%s" ' % (location , fileName) ) if __name__ == "__main__": mongoConnection.drop_database('cloudDB') savePhysicalMachines(getPhysicalMachines(argv[1])) saveImageFiles(getImageFiles(argv[2])) saveVMTypes(getVMTypesDict(argv[3])) copyImagesToServer()
class TypesTestCase(unittest.TestCase): def setUp(self): self.connection = Connection() self.col = self.connection['test']['mongokit'] def tearDown(self): self.connection.drop_database('test') def test_authorized_type(self): for auth_type in SchemaDocument.authorized_types: if auth_type is dict: auth_type = {} class MyDoc(SchemaDocument): structure = {"foo": auth_type} if type(auth_type) is dict: assert MyDoc() == {"foo": {}}, MyDoc() elif auth_type is list: assert MyDoc() == {"foo": []} else: assert MyDoc() == {"foo": None}, auth_type def test_not_authorized_type(self): for unauth_type in [set]: failed = False try: class MyDoc(SchemaDocument): structure = {"foo": [unauth_type]} except StructureError as e: self.assertEqual( str(e), "MyDoc: %s is not an authorized type" % unauth_type) failed = True self.assertEqual(failed, True) failed = False try: class MyDoc(SchemaDocument): structure = {"foo": (unauth_type)} except StructureError as e: self.assertEqual( str(e), "MyDoc: %s is not an authorized type" % unauth_type) failed = True self.assertEqual(failed, True) failed = False try: class MyDoc2(SchemaDocument): structure = {'foo': [{int: unauth_type}]} except StructureError as e: self.assertEqual( str(e), "MyDoc2: %s is not an authorized type" % unauth_type) failed = True self.assertEqual(failed, True) failed = False try: class MyDoc3(SchemaDocument): structure = {'foo': [{unauth_type: int}]} except AuthorizedTypeError as e: self.assertEqual( str(e), "MyDoc3: %s is not an authorized type" % unauth_type) failed = True self.assertEqual(failed, True) failed = False try: class MyDoc4(SchemaDocument): structure = {1: six.text_type} except StructureError as e: self.assertEqual(str(e), "MyDoc4: 1 must be a string or a type") failed = True self.assertEqual(failed, True) def test_type_from_functions(self): from datetime import datetime class MyDoc(SchemaDocument): structure = { "foo": datetime, } assert MyDoc() == {"foo": None}, MyDoc() mydoc = MyDoc() mydoc['foo'] = datetime.now() mydoc.validate() def test_non_typed_list(self): class MyDoc(SchemaDocument): structure = {"foo": []} mydoc = MyDoc() mydoc.validate() assert mydoc['foo'] == [] mydoc['foo'] = [u"bla", 23] mydoc.validate() mydoc['foo'] = [set([1, 2]), "bla"] self.assertRaises(AuthorizedTypeError, mydoc.validate) mydoc['foo'] = u"bla" self.assertRaises(SchemaTypeError, mydoc.validate) # class MyDoc(SchemaDocument): # structure = { # "foo":list # } # mydoc = MyDoc() # mydoc.validate() # assert mydoc['foo'] == [] # mydoc['foo'] = [u"bla", 23] # mydoc.validate() # mydoc['foo'] = [set([1,2]), "bla"] # self.assertRaises(AuthorizedTypeError, mydoc.validate) def test_typed_list(self): class MyDoc(SchemaDocument): structure = {"foo": [int]} mydoc = MyDoc() mydoc.validate() assert mydoc['foo'] == [] mydoc['foo'] = [1, 2, 3] mydoc.validate() mydoc['foo'] = [u"bla"] self.assertRaises(SchemaTypeError, mydoc.validate) def test_typed_list_with_dict(self): class MyDoc(SchemaDocument): structure = {"foo": [{six.text_type: int}]} mydoc = MyDoc() mydoc['foo'] = [{u"bla": 1}, {u"ble": 2}] mydoc.validate() mydoc['foo'] = [{u"bla": u"bar"}] self.assertRaises(SchemaTypeError, mydoc.validate) def test_typed_list_with_list(self): class MyDoc(SchemaDocument): structure = {"foo": [[six.text_type]]} mydoc = MyDoc() mydoc['foo'] = [[u"bla", u"blu"], [u"ble", u"bli"]] mydoc.validate() mydoc['foo'] = [[u"bla", 1]] self.assertRaises(SchemaTypeError, mydoc.validate) def test_typed_tuple(self): class MyDoc(SchemaDocument): structure = {"foo": (int, six.text_type, float)} mydoc = MyDoc() mydoc.validate() assert mydoc['foo'] == [None, None, None] mydoc['foo'] = [u"bla", 1, 4.0] self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo'] = [1, u"bla"] self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo'] = u"bla" self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo'] = [1, u'bar', 3.2] mydoc.validate() mydoc['foo'] = [None, u"bla", 3.1] mydoc.validate() mydoc['foo'][0] = 50 mydoc.validate() def test_nested_typed_tuple(self): class MyDoc(SchemaDocument): structure = {"foo": {'bar': (int, six.text_type, float)}} mydoc = MyDoc() mydoc.validate() assert mydoc['foo']['bar'] == [None, None, None] mydoc['foo']['bar'] = [u"bla", 1, 4.0] self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo']['bar'] = [1, u"bla"] self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo']['bar'] = [1, u'bar', 3.2] mydoc.validate() mydoc['foo']['bar'] = [None, u"bla", 3.1] mydoc.validate() mydoc['foo']['bar'][0] = 50 mydoc.validate() def test_saving_tuple(self): class MyDoc(Document): structure = {'foo': (int, six.text_type, float)} self.connection.register([MyDoc]) mydoc = self.col.MyDoc() assert mydoc == {'foo': [None, None, None]}, mydoc mydoc['foo'] = (1, u'a', 1.1 ) # note that this will be converted to list assert mydoc == {'foo': (1, u'a', 1.1000000000000001)}, mydoc mydoc.save() mydoc = self.col.find_one() class MyDoc(Document): structure = {'foo': [six.text_type]} self.connection.register([]) self.connection.register([MyDoc]) mydoc = self.col.MyDoc() mydoc['foo'] = (u'bla', u'bli', u'blu', u'bly') mydoc.save() mydoc = self.col.get_from_id(mydoc['_id']) def test_nested_typed_tuple_in_list(self): class MyDoc(SchemaDocument): structure = {"foo": {'bar': [(int, six.text_type, float)]}} mydoc = MyDoc() mydoc.validate() assert mydoc == {'foo': {'bar': []}} mydoc['foo']['bar'].append([u"bla", 1, 4.0]) self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo']['bar'] = [] mydoc['foo']['bar'].append([1, u"bla"]) self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo']['bar'] = [] mydoc['foo']['bar'].append([1, u'bar', 3.2]) mydoc.validate() mydoc['foo']['bar'].append([None, u"bla", 3.1]) mydoc.validate() mydoc['foo']['bar'][1][0] = 50 mydoc.validate() def test_dict_unicode_typed_list(self): class MyDoc(SchemaDocument): structure = {"foo": {six.text_type: [int]}} mydoc = MyDoc() mydoc['foo'] = {u"bar": [1, 2, 3]} mydoc.validate() mydoc['foo'] = {u"bar": [u"bla"]} self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo'] = {3: [1, 2, 3]} self.assertRaises(SchemaTypeError, mydoc.validate) def test_with_custom_object(self): class MyDict(dict): pass class MyDoc(SchemaDocument): structure = {"foo": {six.text_type: int}} mydoc = MyDoc() mydict = MyDict() mydict[u"foo"] = 3 mydoc["foo"] = mydict mydoc.validate() def test_custom_object_as_type(self): class MyDict(dict): pass class MyDoc(SchemaDocument): structure = {"foo": MyDict({six.text_type: int})} mydoc = MyDoc() mydict = MyDict() mydict[u"foo"] = 3 mydoc["foo"] = mydict mydoc.validate() mydoc['foo'] = {u"foo": "7"} self.assertRaises(SchemaTypeError, mydoc.validate) class MyInt(int): pass class MyDoc(SchemaDocument): structure = { "foo": MyInt, } mydoc = MyDoc() mydoc["foo"] = MyInt(3) mydoc.validate() mydoc['foo'] = 3 self.assertRaises(SchemaTypeError, mydoc.validate) def test_list_instead_of_dict(self): class MyDoc(SchemaDocument): structure = {"foo": {six.text_type: [six.text_type]}} mydoc = MyDoc() mydoc['foo'] = [u'bla'] self.assertRaises(SchemaTypeError, mydoc.validate) def _test_big_nested_example(self): # XXX TODO class MyDoc(SchemaDocument): structure = { "foo": { six.text_type: [int], u"bar": { "spam": { int: [six.text_type] } } }, "bla": { "blo": { "bli": [{ "arf": six.text_type }] } }, } mydoc = MyDoc() mydoc['foo'].update({u"bir": [1, 2, 3]}) mydoc['foo'][u'bar'][u'spam'] = { 1: [u'bla', u'ble'], 3: [u'foo', u'bar'] } mydoc.validate() mydoc['bla']['blo']['bli'] = [{u"bar": [u"bla"]}] self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['bla']['blo']['bli'] = [{u"arf": [1]}] self.assertRaises(SchemaTypeError, mydoc.validate) def test_adding_custom_type(self): class MyDoc(SchemaDocument): structure = { "foo": str, } authorized_types = SchemaDocument.authorized_types + [str] mydoc = MyDoc() def test_schema_operator(self): from mongokit.operators import SchemaOperator class OP(SchemaOperator): repr = "op" op = OP() self.assertRaises(NotImplementedError, op.validate, "bla") def test_or_operator(self): from mongokit import OR assert repr(OR(int, str)) == "<int or str>" failed = False try: class BadMyDoc(SchemaDocument): structure = {"bla": OR(int, tuple)} except StructureError as e: self.assertEqual( str(e), "BadMyDoc: <%s 'tuple'> in <int or tuple> is not an authorized type (type found)" % ('type' if six.PY2 else 'class')) failed = True self.assertEqual(failed, True) from datetime import datetime if six.PY2: string_type = basestring else: string_type = str class MyDoc(SchemaDocument): structure = { "foo": OR(six.text_type, int), "bar": OR(six.text_type, datetime), "foobar": OR(string_type, int), } mydoc = MyDoc() assert str( mydoc.structure['foo']) == '<%s or int>' % six.text_type.__name__ assert str(mydoc.structure['bar'] ) == '<%s or datetime>' % six.text_type.__name__ assert str( mydoc.structure['foobar']) == '<%s or int>' % string_type.__name__ assert mydoc == {'foo': None, 'bar': None, 'foobar': None} mydoc['foo'] = 3.0 self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo'] = six.u("foo") mydoc.validate() mydoc['foo'] = 3 mydoc.validate() mydoc['foo'] = 'bar' if six.PY2: self.assertRaises(SchemaTypeError, mydoc.validate) else: mydoc.validate() mydoc['foo'] = datetime.now() self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo'] = six.u("foo") mydoc['bar'] = datetime.now() mydoc.validate() mydoc['bar'] = six.u("today") mydoc.validate() mydoc['bar'] = 25 self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['bar'] = six.u("bar") mydoc["foo"] = six.u("foo") mydoc["foobar"] = "foobar" mydoc.validate() mydoc["foobar"] = datetime.now() self.assertRaises(SchemaTypeError, mydoc.validate) mydoc["foobar"] = 3 mydoc.validate() def test_not_operator(self): from mongokit import NOT failed = False try: class BadMyDoc(SchemaDocument): structure = {"bla": NOT(int, tuple)} except StructureError as e: self.assertEqual( str(e), "BadMyDoc: <%s 'tuple'> in <not int, not tuple> is not an authorized type (type found)" % ('type' if six.PY2 else 'class')) failed = True self.assertEqual(failed, True) from datetime import datetime if six.PY2: string_type = basestring else: string_type = str class MyDoc(SchemaDocument): structure = { "foo": NOT(six.text_type, int), "bar": NOT(datetime), "foobar": NOT(string_type) } mydoc = MyDoc() assert str(mydoc.structure['foo'] ) == '<not %s, not int>' % six.text_type.__name__, str( mydoc.structure['foo']) assert str(mydoc.structure['bar']) == '<not datetime>' assert str( mydoc.structure['foobar']) == '<not %s>' % string_type.__name__ assert mydoc == {'foo': None, 'bar': None, 'foobar': None} assert mydoc['foo'] is None assert mydoc['bar'] is None assert mydoc['foobar'] is None mydoc['foo'] = 3 self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo'] = u"foo" self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo'] = 3.0 mydoc.validate() mydoc['foo'] = datetime.now() mydoc.validate() mydoc['bar'] = datetime.now() self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['bar'] = u"today" mydoc.validate() mydoc['bar'] = 25 mydoc.validate() mydoc['foobar'] = 'abc' self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foobar'] = 1 mydoc.validate() def test_is_operator(self): from mongokit import IS failed = False try: class BadMyDoc(SchemaDocument): structure = {"bla": IS(('bla', ), 3)} except StructureError as e: self.assertEqual( str(e), "BadMyDoc: ('bla',) in <is ('bla',) or is 3> is not an authorized type (tuple found)" ) failed = True self.assertEqual(failed, True) from datetime import datetime class MyDoc(SchemaDocument): structure = {"foo": IS(u'spam', u'eggs'), "bar": IS(u'3', 3)} mydoc = MyDoc() if six.PY2: assert str(mydoc.structure['foo']) == "<is u'spam' or is u'eggs'>" assert str(mydoc.structure['bar']) == "<is u'3' or is 3>" else: assert str(mydoc.structure['foo']) == "<is 'spam' or is 'eggs'>" assert str(mydoc.structure['bar']) == "<is '3' or is 3>" assert mydoc == {'foo': None, 'bar': None} assert mydoc['foo'] is None assert mydoc['bar'] is None mydoc['foo'] = 3 self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo'] = u"bla" self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo'] = datetime.now() self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo'] = u"spam" mydoc.validate() mydoc['foo'] = u"eggs" mydoc.validate() mydoc['bar'] = datetime.now() self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['bar'] = u"today" self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['bar'] = 'foo' self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['bar'] = 3 mydoc.validate() mydoc['bar'] = u"3" mydoc.validate() def test_subclassed_type(self): """ accept all subclass of supported type """ class CustomFloat(float): def __init__(self, float): self = float + 2 class MyDoc(SchemaDocument): structure = { "foo": float, } mydoc = MyDoc() mydoc['foo'] = CustomFloat(4) mydoc.validate() def test_set_type(self): from mongokit import Set class MyDoc(Document): structure = { "tags": Set(int), } self.connection.register([MyDoc]) mydoc = self.col.MyDoc() mydoc['tags'] = set(["1", "1", "2", "3", "4"]) self.assertRaises(ValueError, mydoc.validate) mydoc['tags'] = set([1, 1, 2, 3, 4]) mydoc.save() doc = self.col.MyDoc.find_one() assert doc['tags'] == set([1, 2, 3, 4]), doc['tags'] def test_set_type2(self): class MyDoc(Document): structure = { 'title': six.text_type, 'category': Set(six.text_type) } required_fields = ['title'] self.connection.register([MyDoc]) doc = self.col.MyDoc() print(doc) # {'category': set([]), 'title': None} assert isinstance(doc['category'], set) try: doc.validate() except RequireFieldError as e: print(e) # title is required print(doc) # {'category': [], 'title': None} assert isinstance(doc['category'], set) doc['title'] = u'hello' doc.validate() def test_int_type(self): @self.connection.register class MyDoc(Document): structure = { "foo": int, } mydoc = self.col.MyDoc() mydoc['foo'] = '' self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo'] = 10 mydoc.save() def test_uuid_type(self): import uuid @self.connection.register class MyDoc(Document): structure = { 'uuid': uuid.UUID, } uid = uuid.uuid4() obj = self.col.MyDoc() obj['uuid'] = uid obj.save() assert isinstance(self.col.MyDoc.find_one()['uuid'], uuid.UUID) if six.PY2: def test_binary_with_str_type(self): import bson six.text_type @self.connection.register class MyDoc(Document): structure = { 'my_binary': basestring, } obj = self.col.MyDoc() # non-utf8 string non_utf8 = "\xFF\xFE\xFF" obj['my_binary'] = non_utf8 self.assertRaises(bson.errors.InvalidStringData, obj.validate) def test_binary_with_unicode_type(self): import bson @self.connection.register class MyDoc(Document): structure = { 'my_binary': unicode, } obj = self.col.MyDoc() # non-utf8 string non_utf8 = "\xFF\xFE\xFF" obj['my_binary'] = non_utf8 self.assertRaises(bson.errors.InvalidStringData, obj.validate) def test_binary_with_binary_type(self): import bson @self.connection.register class MyDoc(Document): structure = { 'my_binary': bson.binary.Binary, } obj = self.col.MyDoc() # non-utf8 string string = "\xFF\xFE\xFF" if six.PY3: bin_obj = bson.binary.Binary(bytes(string, 'utf-8')) else: bin_obj = bson.binary.Binary(string) obj['my_binary'] = bin_obj obj.save() db_obj = bson.binary.Binary(self.col.MyDoc.find_one()['my_binary']) self.assertEquals(db_obj, bin_obj)
class InheritedQueriesTestCase(unittest.TestCase): def setUp(self): self.connection = Connection(safe=True) self.col = self.connection['test']['mongolite'] def tearDown(self): self.connection.drop_database('test') def test_use_inherited_queries(self): @self.connection.register class A(Document): __database__ = 'test' __collection__ = 'mongolite' structure = { '_type': str, 'a': { 'foo': int, 'bar': str, } } @self.connection.register class B(A): structure = { 'b': { 'eggs': float, } } doc_a = self.connection.A() self.assertEqual(doc_a['_type'], 'A') doc_a['a']['foo'] = 3 doc_a['a']['bar'] = 'Hello World' doc_a.save() doc_b = self.connection.B() self.assertEqual(doc_b['_type'], 'B') doc_b['a']['foo'] = 42 doc_b['a']['bar'] = 'bye bye' doc_b['b']['eggs'] = 3.14 doc_b.save() self.assertTrue( isinstance(self.connection.A.find_one({'_id': doc_b['_id']}), B)) self.assertTrue( isinstance( self.connection.A.find({ '_id': doc_b['_id'] }).next(), B)) self.assertTrue( isinstance(self.connection.A.find({'_id': doc_b['_id']})[0], B)) def test_inherited_queries_without___collection__(self): @self.connection.register class A(Document): structure = { '_type': str, 'a': { 'foo': int, 'bar': str, } } @self.connection.register class B(A): structure = { 'b': { 'eggs': float, } } doc_a = self.col.A() self.assertEqual(doc_a['_type'], 'A') doc_a['a']['foo'] = 3 doc_a['a']['bar'] = 'Hello World' doc_a.save() doc_b = self.col.B() self.assertEqual(doc_b['_type'], 'B') doc_b['a']['foo'] = 42 doc_b['a']['bar'] = 'bye bye' doc_b['b']['eggs'] = 3.14 doc_b.save() self.assertTrue( isinstance(self.col.A.find_one({'_id': doc_b['_id']}), B)) self.assertTrue( isinstance(self.col.A.find({ '_id': doc_b['_id'] }).next(), B)) self.assertTrue( isinstance(self.col.A.find({'_id': doc_b['_id']})[0], B)) def test_type_field_is_None(self): @self.connection.register class A(Document): type_field = None structure = { '_type': str, 'a': { 'foo': int, 'bar': str, } } @self.connection.register class B(A): structure = { 'b': { 'eggs': float, } } doc_a = self.col.A() self.assertEqual(doc_a['_type'], None) doc_a['a']['foo'] = 3 doc_a['a']['bar'] = 'Hello World' doc_a.save() doc_b = self.col.B() self.assertEqual(doc_b['_type'], None) doc_b['a']['foo'] = 42 doc_b['a']['bar'] = 'bye bye' doc_b['b']['eggs'] = 3.14 doc_b.save() self.assertTrue( isinstance(self.col.A.find_one({'_id': doc_b['_id']}), A)) self.assertTrue( isinstance(self.col.A.find({ '_id': doc_b['_id'] }).next(), A)) self.assertFalse( isinstance(self.col.A.find_one({'_id': doc_b['_id']}), B)) self.assertFalse( isinstance(self.col.A.find({ '_id': doc_b['_id'] }).next(), B)) def test_no__type(self): @self.connection.register class A(Document): structure = { 'a': { 'foo': int, 'bar': str, } } @self.connection.register class B(A): structure = { 'b': { 'eggs': float, } } doc_a = self.col.A() self.assertTrue('_type' not in doc_a) doc_a['a']['foo'] = 3 doc_a['a']['bar'] = 'Hello World' doc_a.save() doc_b = self.col.B() self.assertTrue('_type' not in doc_b) doc_b['a']['foo'] = 42 doc_b['a']['bar'] = 'bye bye' doc_b['b']['eggs'] = 3.14 doc_b.save() self.assertTrue( isinstance(self.col.A.find_one({'_id': doc_b['_id']}), A)) self.assertTrue( isinstance(self.col.A.find({ '_id': doc_b['_id'] }).next(), A)) self.assertFalse( isinstance(self.col.A.find_one({'_id': doc_b['_id']}), B)) self.assertFalse( isinstance(self.col.A.find({ '_id': doc_b['_id'] }).next(), B)) def test_change_type_field(self): @self.connection.register class A(Document): type_field = '_t' structure = { '_type': str, '_t': str, 'a': { 'foo': int, 'bar': str, } } @self.connection.register class B(A): structure = { 'b': { 'eggs': float, } } doc_a = self.col.A() self.assertEqual(doc_a['_type'], None) self.assertEqual(doc_a['_t'], 'A') doc_a['a']['foo'] = 3 doc_a['a']['bar'] = 'Hello World' doc_a.save() doc_b = self.col.B() self.assertEqual(doc_b['_type'], None) self.assertEqual(doc_b['_t'], 'B') doc_b['a']['foo'] = 42 doc_b['a']['bar'] = 'bye bye' doc_b['b']['eggs'] = 3.14 doc_b.save() self.assertTrue( isinstance(self.col.A.find_one({'_id': doc_b['_id']}), A)) self.assertTrue( isinstance(self.col.A.find({ '_id': doc_b['_id'] }).next(), A)) self.assertTrue( isinstance(self.col.A.find_one({'_id': doc_b['_id']}), B)) self.assertTrue( isinstance(self.col.A.find({ '_id': doc_b['_id'] }).next(), B))
class DescriptorsTestCase(unittest.TestCase): def setUp(self): self.connection = Connection() self.col = self.connection['test']['mongokit'] def tearDown(self): self.connection.drop_database('test') def test_list_embed_dot_notation(self): """Attempt to set a default for a sub element using dot notation Either this or test_list_embed_list_notation should pass """ class ListEmbed(Document): use_dot_notation = True structure = { 'list': [ { 'name': basestring, 'age': int } ] } default_values = { 'list.name': 'default' } self.connection.register([ListEmbed]) doc = self.col.ListEmbed() self.assertDictEqual(doc, {'list': []}) doc.list.append({'age': 23}) self.assertDictEqual( doc, { 'list': [ { 'name': 'default', 'age': 23 } ] } ) def test_list_embed_list_notation(self): """Attempt to set a default for a sub element using list notation Either this or test_list_embed_dot_notation should pass """ class ListEmbed(Document): use_dot_notation = True structure = { 'list': [ { 'name': basestring, 'age': int } ] } default_values = { 'list': [ { 'name': 'default' } ] } self.connection.register([ListEmbed]) doc = self.col.ListEmbed() self.assertDictEqual(doc, {'list': []}) doc.list.append({'age': 23}) self.assertDictEqual( doc, { 'list': [ { 'name': 'default', 'age': 23 } ] } ) def test_list_embed_non_required_fields(self): """Confirm all fields are not required""" class ListEmbed(Document): use_dot_notation = True structure = { 'list': [ { 'name': basestring, 'age': int } ] } self.connection.register([ListEmbed]) doc = self.col.ListEmbed() self.assertDictEqual(doc, {'list': []}) doc.list.append({'age': 23}) self.assertDictEqual( doc, { 'list': [ { 'age': 23 } ] } ) # Should validate fine doc.validate() def test_list_embed_required_fields_dot_notation(self): """Confirm list of object required field validation works""" class ListEmbed(Document): use_dot_notation = True structure = { 'list': [ { 'name': basestring, 'age': int } ] } required_fields = ['list.name'] self.connection.register([ListEmbed]) doc = self.col.ListEmbed() self.assertDictEqual(doc, {'list': []}) doc.list = [{'name': 'bob'}] self.assertDictEqual( doc, { 'list': [ { 'name': 'bob' } ] } ) # Should validate fine doc.validate() doc.list = [{'age': 23}] self.assertDictEqual( doc, { 'list': [ { 'age': 23 } ] } ) try: doc.validate() self.fail('Not a valid document') except: pass
class TypesTestCase(unittest.TestCase): def setUp(self): self.connection = Connection() self.col = self.connection['test']['mongokit'] def tearDown(self): self.connection.drop_database('test') def test_authorized_type(self): for auth_type in SchemaDocument.authorized_types: if auth_type is dict: auth_type = {} class MyDoc(SchemaDocument): structure = { "foo":auth_type } if type(auth_type) is dict: assert MyDoc() == {"foo":{}}, MyDoc() elif auth_type is list: assert MyDoc() == {"foo":[]} else: assert MyDoc() == {"foo":None}, auth_type def test_not_authorized_type(self): for unauth_type in [set, str]: class MyDoc(SchemaDocument): structure = { "foo":[unauth_type] } self.assertRaises( StructureError, MyDoc ) class MyDoc(SchemaDocument): structure = { "foo":(unauth_type) } self.assertRaises( StructureError, MyDoc ) class MyDoc2(SchemaDocument): structure = { 'foo':[{int:unauth_type }]} self.assertRaises( StructureError, MyDoc2 ) class MyDoc3(SchemaDocument): structure = { 'foo':[{unauth_type:int }]} self.assertRaises( AuthorizedTypeError, MyDoc3 ) class MyDoc4(SchemaDocument): structure = {1:unicode} self.assertRaises( StructureError, MyDoc4 ) def test_type_from_functions(self): from datetime import datetime class MyDoc(SchemaDocument): structure = { "foo":datetime, } assert MyDoc() == {"foo":None}, MyDoc() mydoc = MyDoc() mydoc['foo'] = datetime.now() mydoc.validate() def test_non_typed_list(self): class MyDoc(SchemaDocument): structure = { "foo":[] } mydoc = MyDoc() mydoc.validate() assert mydoc['foo'] == [] mydoc['foo'] = [u"bla", 23] mydoc.validate() mydoc['foo'] = [set([1,2]), "bla"] self.assertRaises(AuthorizedTypeError, mydoc.validate) mydoc['foo'] = u"bla" self.assertRaises(SchemaTypeError, mydoc.validate) # class MyDoc(SchemaDocument): # structure = { # "foo":list # } # mydoc = MyDoc() # mydoc.validate() # assert mydoc['foo'] == [] # mydoc['foo'] = [u"bla", 23] # mydoc.validate() # mydoc['foo'] = [set([1,2]), "bla"] # self.assertRaises(AuthorizedTypeError, mydoc.validate) def test_typed_list(self): class MyDoc(SchemaDocument): structure = { "foo":[int] } mydoc = MyDoc() mydoc.validate() assert mydoc['foo'] == [] mydoc['foo'] = [1,2,3] mydoc.validate() mydoc['foo'] = [u"bla"] self.assertRaises(SchemaTypeError, mydoc.validate) def test_typed_list_with_dict(self): class MyDoc(SchemaDocument): structure = { "foo":[{unicode:int}] } mydoc = MyDoc() mydoc['foo'] = [{u"bla":1},{u"ble":2}] mydoc.validate() mydoc['foo'] = [{u"bla":u"bar"}] self.assertRaises(SchemaTypeError, mydoc.validate) def test_typed_list_with_list(self): class MyDoc(SchemaDocument): structure = { "foo":[[unicode]] } mydoc = MyDoc() mydoc['foo'] = [[u"bla",u"blu"],[u"ble",u"bli"]] mydoc.validate() mydoc['foo'] = [[u"bla",1]] self.assertRaises(SchemaTypeError, mydoc.validate) def test_typed_tuple(self): class MyDoc(SchemaDocument): structure = { "foo":(int, unicode, float) } mydoc = MyDoc() mydoc.validate() assert mydoc['foo'] == [None, None, None] mydoc['foo'] = [u"bla", 1, 4.0] self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo'] = [1, u"bla"] self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo'] = u"bla" self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo'] = [1,u'bar',3.2] mydoc.validate() mydoc['foo'] = [None, u"bla", 3.1] mydoc.validate() mydoc['foo'][0] = 50 mydoc.validate() def test_nested_typed_tuple(self): class MyDoc(SchemaDocument): structure = { "foo":{'bar':(int, unicode, float)} } mydoc = MyDoc() mydoc.validate() assert mydoc['foo']['bar'] == [None, None, None] mydoc['foo']['bar'] = [u"bla", 1, 4.0] self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo']['bar'] = [1, u"bla"] self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo']['bar'] = [1,u'bar',3.2] mydoc.validate() mydoc['foo']['bar'] = [None, u"bla", 3.1] mydoc.validate() mydoc['foo']['bar'][0] = 50 mydoc.validate() def test_saving_tuple(self): class MyDoc(Document): structure = { 'foo': (int, unicode, float) } self.connection.register([MyDoc]) mydoc = self.col.MyDoc() assert mydoc == {'foo': [None, None, None]}, mydoc mydoc['foo'] = (1, u'a', 1.1) # note that this will be converted to list assert mydoc == {'foo': (1, u'a', 1.1000000000000001)}, mydoc mydoc.save() mydoc = self.col.find_one() class MyDoc(Document): structure = {'foo':[unicode]} self.connection.register([]) self.connection.register([MyDoc]) mydoc = self.col.MyDoc() mydoc['foo'] = (u'bla', u'bli', u'blu', u'bly') mydoc.save() mydoc = self.col.get_from_id(mydoc['_id']) def test_nested_typed_tuple_in_list(self): class MyDoc(SchemaDocument): structure = { "foo":{'bar':[(int, unicode, float)]} } mydoc = MyDoc() mydoc.validate() assert mydoc == {'foo': {'bar': []}} mydoc['foo']['bar'].append([u"bla", 1, 4.0]) self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo']['bar'] = [] mydoc['foo']['bar'].append([1, u"bla"]) self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo']['bar'] = [] mydoc['foo']['bar'].append([1,u'bar',3.2]) mydoc.validate() mydoc['foo']['bar'].append([None, u"bla", 3.1]) mydoc.validate() mydoc['foo']['bar'][1][0] = 50 mydoc.validate() def test_dict_unicode_typed_list(self): class MyDoc(SchemaDocument): structure = { "foo":{unicode:[int]} } mydoc = MyDoc() mydoc['foo'] = {u"bar":[1,2,3]} mydoc.validate() mydoc['foo'] = {u"bar":[u"bla"]} self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo'] = {3:[1,2,3]} self.assertRaises(SchemaTypeError, mydoc.validate) def test_with_custom_object(self): class MyDict(dict): pass class MyDoc(SchemaDocument): structure = { "foo":{unicode:int} } mydoc = MyDoc() mydict = MyDict() mydict[u"foo"] = 3 mydoc["foo"] = mydict mydoc.validate() def test_custom_object_as_type(self): class MyDict(dict): pass class MyDoc(SchemaDocument): structure = { "foo":MyDict({unicode:int}) } mydoc = MyDoc() mydict = MyDict() mydict[u"foo"] = 3 mydoc["foo"] = mydict mydoc.validate() mydoc['foo'] = {u"foo":"7"} self.assertRaises(SchemaTypeError, mydoc.validate) class MyInt(int): pass class MyDoc(SchemaDocument): structure = { "foo":MyInt, } mydoc = MyDoc() mydoc["foo"] = MyInt(3) mydoc.validate() mydoc['foo'] = 3 self.assertRaises(SchemaTypeError, mydoc.validate) def test_list_instead_of_dict(self): class MyDoc(SchemaDocument): structure = { "foo":{unicode:[unicode]} } mydoc = MyDoc() mydoc['foo'] = [u'bla'] self.assertRaises(SchemaTypeError, mydoc.validate) def _test_big_nested_example(self): # XXX TODO class MyDoc(SchemaDocument): structure = { "foo":{unicode:[int], u"bar":{"spam":{int:[unicode]}}}, "bla":{"blo":{"bli":[{"arf":unicode}]}}, } mydoc = MyDoc() mydoc['foo'].update({u"bir":[1,2,3]}) mydoc['foo'][u'bar'][u'spam'] = {1:[u'bla', u'ble'], 3:[u'foo', u'bar']} mydoc.validate() mydoc['bla']['blo']['bli'] = [{u"bar":[u"bla"]}] self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['bla']['blo']['bli'] = [{u"arf":[1]}] self.assertRaises(SchemaTypeError, mydoc.validate) def test_adding_custom_type(self): class MyDoc(SchemaDocument): structure = { "foo":str, } authorized_types = SchemaDocument.authorized_types + [str] mydoc = MyDoc() def test_schema_operator(self): from mongokit.operators import SchemaOperator class OP(SchemaOperator): repr = "op" op = OP() self.assertRaises(NotImplementedError, op.validate, "bla") def test_or_operator(self): from mongokit import OR assert repr(OR(unicode, str)) == "<unicode or str>" class BadMyDoc(SchemaDocument): structure = {"bla":OR(unicode,str)} self.assertRaises(StructureError, BadMyDoc) from datetime import datetime class MyDoc(SchemaDocument): structure = { "foo":OR(unicode,int), "bar":OR(unicode, datetime) } mydoc = MyDoc() assert str(mydoc.structure['foo']) == '<unicode or int>' assert str(mydoc.structure['bar']) == '<unicode or datetime>' assert mydoc == {'foo': None, 'bar': None} mydoc['foo'] = 3.0 self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo'] = u"foo" mydoc.validate() mydoc['foo'] = 3 mydoc.validate() mydoc['foo'] = 'bar' self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo'] = datetime.now() self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo'] = u"foo" mydoc['bar'] = datetime.now() mydoc.validate() mydoc['bar'] = u"today" mydoc.validate() mydoc['bar'] = 25 self.assertRaises(SchemaTypeError, mydoc.validate) def test_not_operator(self): from mongokit import NOT class BadMyDoc(SchemaDocument): structure = {"bla":NOT(unicode,str)} self.assertRaises(StructureError, BadMyDoc) from datetime import datetime class MyDoc(SchemaDocument): structure = { "foo":NOT(unicode,int), "bar":NOT(datetime) } mydoc = MyDoc() assert str(mydoc.structure['foo']) == '<not unicode, not int>', str(mydoc.structure['foo']) assert str(mydoc.structure['bar']) == '<not datetime>' assert mydoc == {'foo': None, 'bar': None} assert mydoc['foo'] is None assert mydoc['bar'] is None mydoc['foo'] = 3 self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo'] = u"foo" self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo'] = 3.0 mydoc.validate() mydoc['foo'] = datetime.now() mydoc.validate() mydoc['bar'] = datetime.now() self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['bar'] = u"today" mydoc.validate() mydoc['bar'] = 25 mydoc.validate() def test_is_operator(self): from mongokit import IS class BadMyDoc(SchemaDocument): structure = {"bla":IS('bla',3)} self.assertRaises(StructureError, BadMyDoc) from datetime import datetime class MyDoc(SchemaDocument): structure = { "foo":IS(u'spam',u'eggs'), "bar":IS(u'3', 3) } mydoc = MyDoc() assert str(mydoc.structure['foo']) == "<is u'spam' or is u'eggs'>" assert str(mydoc.structure['bar']) == "<is u'3' or is 3>" assert mydoc == {'foo': None, 'bar': None} assert mydoc['foo'] is None assert mydoc['bar'] is None mydoc['foo'] = 3 self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo'] = u"bla" self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo'] = datetime.now() self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo'] = u"spam" mydoc.validate() mydoc['foo'] = u"eggs" mydoc.validate() mydoc['bar'] = datetime.now() self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['bar'] = u"today" self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['bar'] = 'foo' self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['bar'] = 3 mydoc.validate() mydoc['bar'] = u"3" mydoc.validate() def test_subclassed_type(self): """ accept all subclass of supported type """ class CustomFloat(float): def __init__(self, float): self = float + 2 class MyDoc(SchemaDocument): structure = { "foo":float, } mydoc = MyDoc() mydoc['foo'] = CustomFloat(4) mydoc.validate() def test_set_type(self): from mongokit import Set class MyDoc(Document): structure = { "tags":Set(int), } self.connection.register([MyDoc]) mydoc = self.col.MyDoc() mydoc['tags'] = set(["1","1","2","3","4"]) self.assertRaises(ValueError, mydoc.validate) mydoc['tags'] = set([1,1,2,3,4]) mydoc.save() doc = self.col.MyDoc.find_one() assert doc['tags'] == set([1,2,3,4]), doc['tags']
class DescriptorsTestCase(unittest.TestCase): def setUp(self): self.connection = Connection() self.col = self.connection["test"]["mongokit"] def tearDown(self): self.connection.drop_database("test") def test_list_embed_dot_notation(self): """Attempt to set a default for a sub element using dot notation Either this or test_list_embed_list_notation should pass """ class ListEmbed(Document): use_dot_notation = True structure = {"list": [{"name": basestring, "age": int}]} default_values = {"list.name": "default"} self.connection.register([ListEmbed]) doc = self.col.ListEmbed() self.assertDictEqual(doc, {"list": []}) doc.list.append({"age": 23}) self.assertDictEqual(doc, {"list": [{"name": "default", "age": 23}]}) def test_list_embed_list_notation(self): """Attempt to set a default for a sub element using list notation Either this or test_list_embed_dot_notation should pass """ class ListEmbed(Document): use_dot_notation = True structure = {"list": [{"name": basestring, "age": int}]} default_values = {"list": [{"name": "default"}]} self.connection.register([ListEmbed]) doc = self.col.ListEmbed() self.assertDictEqual(doc, {"list": [{"name": "default"}]}) doc.list[0]["age"] = 23 self.assertDictEqual(doc, {"list": [{"name": "default", "age": 23}]}) def test_list_embed_non_required_fields(self): """Confirm all fields are not required""" class ListEmbed(Document): use_dot_notation = True structure = {"list": [{"name": basestring, "age": int}]} self.connection.register([ListEmbed]) doc = self.col.ListEmbed() self.assertDictEqual(doc, {"list": []}) doc.list.append({"age": 23}) self.assertDictEqual(doc, {"list": [{"age": 23}]}) # Should validate fine doc.validate() def test_list_embed_required_fields_dot_notation(self): """Confirm list of object required field validation works""" class ListEmbed(Document): use_dot_notation = True structure = {"list": [{"name": basestring, "age": int}]} required_fields = ["list.name"] self.connection.register([ListEmbed]) doc = self.col.ListEmbed() self.assertDictEqual(doc, {"list": []}) doc.list = [{"name": "bob"}] self.assertDictEqual(doc, {"list": [{"name": "bob"}]}) # Should validate fine doc.validate() doc.list = [{"age": 23}] self.assertDictEqual(doc, {"list": [{"age": 23}]}) try: doc.validate() self.fail("Not a valid document") except: pass
class InheritedQueriesTestCase(unittest.TestCase): def setUp(self): self.connection = Connection(safe=True) self.col = self.connection['test']['mongolite'] def tearDown(self): self.connection.drop_database('test') def test_use_inherited_queries(self): @self.connection.register class A(Document): __database__ = 'test' __collection__ = 'mongolite' structure = { '_type': unicode, 'a':{ 'foo': int, 'bar': unicode, } } @self.connection.register class B(A): structure = { 'b': { 'eggs': float, } } doc_a = self.connection.A() self.assertEqual(doc_a['_type'], 'A') doc_a['a']['foo'] = 3 doc_a['a']['bar'] = u'Hello World' doc_a.save() doc_b = self.connection.B() self.assertEqual(doc_b['_type'], 'B') doc_b['a']['foo'] = 42 doc_b['a']['bar'] = u'bye bye' doc_b['b']['eggs'] = 3.14 doc_b.save() self.assertTrue(isinstance(self.connection.A.find_one({'_id':doc_b['_id']}), B)) self.assertTrue(isinstance(self.connection.A.find({'_id':doc_b['_id']}).next(), B)) def test_inherited_queries_without___collection__(self): @self.connection.register class A(Document): structure = { '_type': unicode, 'a':{ 'foo': int, 'bar': unicode, } } @self.connection.register class B(A): structure = { 'b': { 'eggs': float, } } doc_a = self.col.A() self.assertEqual(doc_a['_type'], 'A') doc_a['a']['foo'] = 3 doc_a['a']['bar'] = u'Hello World' doc_a.save() doc_b = self.col.B() self.assertEqual(doc_b['_type'], 'B') doc_b['a']['foo'] = 42 doc_b['a']['bar'] = u'bye bye' doc_b['b']['eggs'] = 3.14 doc_b.save() self.assertTrue(isinstance(self.col.A.find_one({'_id':doc_b['_id']}), B)) self.assertTrue(isinstance(self.col.A.find({'_id':doc_b['_id']}).next(), B)) def test_type_field_is_None(self): @self.connection.register class A(Document): type_field = None structure = { '_type': unicode, 'a':{ 'foo': int, 'bar': unicode, } } @self.connection.register class B(A): structure = { 'b': { 'eggs': float, } } doc_a = self.col.A() self.assertEqual(doc_a['_type'], None) doc_a['a']['foo'] = 3 doc_a['a']['bar'] = u'Hello World' doc_a.save() doc_b = self.col.B() self.assertEqual(doc_b['_type'], None) doc_b['a']['foo'] = 42 doc_b['a']['bar'] = u'bye bye' doc_b['b']['eggs'] = 3.14 doc_b.save() self.assertTrue(isinstance(self.col.A.find_one({'_id':doc_b['_id']}), A)) self.assertTrue(isinstance(self.col.A.find({'_id':doc_b['_id']}).next(), A)) self.assertFalse(isinstance(self.col.A.find_one({'_id':doc_b['_id']}), B)) self.assertFalse(isinstance(self.col.A.find({'_id':doc_b['_id']}).next(), B)) def test_no__type(self): @self.connection.register class A(Document): structure = { 'a':{ 'foo': int, 'bar': unicode, } } @self.connection.register class B(A): structure = { 'b': { 'eggs': float, } } doc_a = self.col.A() self.assertTrue('_type' not in doc_a) doc_a['a']['foo'] = 3 doc_a['a']['bar'] = u'Hello World' doc_a.save() doc_b = self.col.B() self.assertTrue('_type' not in doc_b) doc_b['a']['foo'] = 42 doc_b['a']['bar'] = u'bye bye' doc_b['b']['eggs'] = 3.14 doc_b.save() self.assertTrue(isinstance(self.col.A.find_one({'_id':doc_b['_id']}), A)) self.assertTrue(isinstance(self.col.A.find({'_id':doc_b['_id']}).next(), A)) self.assertFalse(isinstance(self.col.A.find_one({'_id':doc_b['_id']}), B)) self.assertFalse(isinstance(self.col.A.find({'_id':doc_b['_id']}).next(), B)) def test_change_type_field(self): @self.connection.register class A(Document): type_field = '_t' structure = { '_type': unicode, '_t': unicode, 'a':{ 'foo': int, 'bar': unicode, } } @self.connection.register class B(A): structure = { 'b': { 'eggs': float, } } doc_a = self.col.A() self.assertEqual(doc_a['_type'], None) self.assertEqual(doc_a['_t'], 'A') doc_a['a']['foo'] = 3 doc_a['a']['bar'] = u'Hello World' doc_a.save() doc_b = self.col.B() self.assertEqual(doc_b['_type'], None) self.assertEqual(doc_b['_t'], 'B') doc_b['a']['foo'] = 42 doc_b['a']['bar'] = u'bye bye' doc_b['b']['eggs'] = 3.14 doc_b.save() self.assertTrue(isinstance(self.col.A.find_one({'_id':doc_b['_id']}), A)) self.assertTrue(isinstance(self.col.A.find({'_id':doc_b['_id']}).next(), A)) self.assertTrue(isinstance(self.col.A.find_one({'_id':doc_b['_id']}), B)) self.assertTrue(isinstance(self.col.A.find({'_id':doc_b['_id']}).next(), B))
class DescriptorsTestCase(unittest.TestCase): def setUp(self): self.connection = Connection() self.col = self.connection['test']['mongokit'] def tearDown(self): self.connection.drop_database('test') def test_list_embed_dot_notation(self): """Attempt to set a default for a sub element using dot notation Either this or test_list_embed_list_notation should pass """ class ListEmbed(Document): use_dot_notation = True structure = {'list': [{'name': basestring, 'age': int}]} default_values = {'list.name': 'default'} self.connection.register([ListEmbed]) doc = self.col.ListEmbed() self.assertDictEqual(doc, {'list': []}) doc.list.append({'age': 23}) self.assertDictEqual(doc, {'list': [{'name': 'default', 'age': 23}]}) def test_list_embed_list_notation(self): """Attempt to set a default for a sub element using list notation Either this or test_list_embed_dot_notation should pass """ class ListEmbed(Document): use_dot_notation = True structure = {'list': [{'name': basestring, 'age': int}]} default_values = {'list': [{'name': 'default'}]} self.connection.register([ListEmbed]) doc = self.col.ListEmbed() self.assertDictEqual(doc, {'list': [{'name': 'default'}]}) doc.list[0]['age'] = 23 self.assertDictEqual(doc, {'list': [{'name': 'default', 'age': 23}]}) def test_list_embed_non_required_fields(self): """Confirm all fields are not required""" class ListEmbed(Document): use_dot_notation = True structure = {'list': [{'name': basestring, 'age': int}]} self.connection.register([ListEmbed]) doc = self.col.ListEmbed() self.assertDictEqual(doc, {'list': []}) doc.list.append({'age': 23}) self.assertDictEqual(doc, {'list': [{'age': 23}]}) # Should validate fine doc.validate() def test_list_embed_required_fields_dot_notation(self): """Confirm list of object required field validation works""" class ListEmbed(Document): use_dot_notation = True structure = {'list': [{'name': basestring, 'age': int}]} required_fields = ['list.name'] self.connection.register([ListEmbed]) doc = self.col.ListEmbed() self.assertDictEqual(doc, {'list': []}) doc.list = [{'name': 'bob'}] self.assertDictEqual(doc, {'list': [{'name': 'bob'}]}) # Should validate fine doc.validate() doc.list = [{'age': 23}] self.assertDictEqual(doc, {'list': [{'age': 23}]}) try: doc.validate() self.fail('Not a valid document') except: pass
class TypesTestCase(unittest.TestCase): def setUp(self): self.connection = Connection() self.col = self.connection['test']['mongokit'] def tearDown(self): self.connection.drop_database('test') def test_authorized_type(self): for auth_type in SchemaDocument.authorized_types: if auth_type is dict: auth_type = {} class MyDoc(SchemaDocument): structure = { "foo":auth_type } if type(auth_type) is dict: assert MyDoc() == {"foo":{}}, MyDoc() elif auth_type is list: assert MyDoc() == {"foo":[]} else: assert MyDoc() == {"foo":None}, auth_type def test_not_authorized_type(self): for unauth_type in [set]: failed = False try: class MyDoc(SchemaDocument): structure = { "foo":[unauth_type] } except StructureError as e: self.assertEqual(str(e), "MyDoc: %s is not an authorized type" % unauth_type) failed = True self.assertEqual(failed, True) failed = False try: class MyDoc(SchemaDocument): structure = { "foo":(unauth_type) } except StructureError as e: self.assertEqual(str(e), "MyDoc: %s is not an authorized type" % unauth_type) failed = True self.assertEqual(failed, True) failed = False try: class MyDoc2(SchemaDocument): structure = { 'foo':[{int:unauth_type }]} except StructureError as e: self.assertEqual(str(e), "MyDoc2: %s is not an authorized type" % unauth_type) failed = True self.assertEqual(failed, True) failed = False try: class MyDoc3(SchemaDocument): structure = { 'foo':[{unauth_type:int }]} except AuthorizedTypeError as e: self.assertEqual(str(e), "MyDoc3: %s is not an authorized type" % unauth_type) failed = True self.assertEqual(failed, True) failed = False try: class MyDoc4(SchemaDocument): structure = {1:str} except StructureError as e: self.assertEqual(str(e), "MyDoc4: 1 must be a string or a type") failed = True self.assertEqual(failed, True) def test_type_from_functions(self): from datetime import datetime class MyDoc(SchemaDocument): structure = { "foo":datetime, } assert MyDoc() == {"foo":None}, MyDoc() mydoc = MyDoc() mydoc['foo'] = datetime.now() mydoc.validate() def test_non_typed_list(self): class MyDoc(SchemaDocument): structure = { "foo":[] } mydoc = MyDoc() mydoc.validate() assert mydoc['foo'] == [] mydoc['foo'] = ["bla", 23] mydoc.validate() mydoc['foo'] = [set([1,2]), "bla"] self.assertRaises(AuthorizedTypeError, mydoc.validate) mydoc['foo'] = "bla" self.assertRaises(SchemaTypeError, mydoc.validate) # class MyDoc(SchemaDocument): # structure = { # "foo":list # } # mydoc = MyDoc() # mydoc.validate() # assert mydoc['foo'] == [] # mydoc['foo'] = [u"bla", 23] # mydoc.validate() # mydoc['foo'] = [set([1,2]), "bla"] # self.assertRaises(AuthorizedTypeError, mydoc.validate) def test_typed_list(self): class MyDoc(SchemaDocument): structure = { "foo":[int] } mydoc = MyDoc() mydoc.validate() assert mydoc['foo'] == [] mydoc['foo'] = [1,2,3] mydoc.validate() mydoc['foo'] = ["bla"] self.assertRaises(SchemaTypeError, mydoc.validate) def test_typed_list_with_dict(self): class MyDoc(SchemaDocument): structure = { "foo":[{str:int}] } mydoc = MyDoc() mydoc['foo'] = [{"bla":1},{"ble":2}] mydoc.validate() mydoc['foo'] = [{"bla":"bar"}] self.assertRaises(SchemaTypeError, mydoc.validate) def test_typed_list_with_list(self): class MyDoc(SchemaDocument): structure = { "foo":[[str]] } mydoc = MyDoc() mydoc['foo'] = [["bla","blu"],["ble","bli"]] mydoc.validate() mydoc['foo'] = [["bla",1]] self.assertRaises(SchemaTypeError, mydoc.validate) def test_typed_tuple(self): class MyDoc(SchemaDocument): structure = { "foo":(int, str, float) } mydoc = MyDoc() mydoc.validate() assert mydoc['foo'] == [None, None, None] mydoc['foo'] = ["bla", 1, 4.0] self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo'] = [1, "bla"] self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo'] = "bla" self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo'] = [1,'bar',3.2] mydoc.validate() mydoc['foo'] = [None, "bla", 3.1] mydoc.validate() mydoc['foo'][0] = 50 mydoc.validate() def test_nested_typed_tuple(self): class MyDoc(SchemaDocument): structure = { "foo":{'bar':(int, str, float)} } mydoc = MyDoc() mydoc.validate() assert mydoc['foo']['bar'] == [None, None, None] mydoc['foo']['bar'] = ["bla", 1, 4.0] self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo']['bar'] = [1, "bla"] self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo']['bar'] = [1,'bar',3.2] mydoc.validate() mydoc['foo']['bar'] = [None, "bla", 3.1] mydoc.validate() mydoc['foo']['bar'][0] = 50 mydoc.validate() def test_saving_tuple(self): class MyDoc(Document): structure = { 'foo': (int, str, float) } self.connection.register([MyDoc]) mydoc = self.col.MyDoc() assert mydoc == {'foo': [None, None, None]}, mydoc mydoc['foo'] = (1, 'a', 1.1) # note that this will be converted to list assert mydoc == {'foo': (1, 'a', 1.1000000000000001)}, mydoc mydoc.save() mydoc = self.col.find_one() class MyDoc(Document): structure = {'foo':[str]} self.connection.register([]) self.connection.register([MyDoc]) mydoc = self.col.MyDoc() mydoc['foo'] = ('bla', 'bli', 'blu', 'bly') mydoc.save() mydoc = self.col.get_from_id(mydoc['_id']) def test_nested_typed_tuple_in_list(self): class MyDoc(SchemaDocument): structure = { "foo":{'bar':[(int, str, float)]} } mydoc = MyDoc() mydoc.validate() assert mydoc == {'foo': {'bar': []}} mydoc['foo']['bar'].append(["bla", 1, 4.0]) self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo']['bar'] = [] mydoc['foo']['bar'].append([1, "bla"]) self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo']['bar'] = [] mydoc['foo']['bar'].append([1,'bar',3.2]) mydoc.validate() mydoc['foo']['bar'].append([None, "bla", 3.1]) mydoc.validate() mydoc['foo']['bar'][1][0] = 50 mydoc.validate() def test_dict_unicode_typed_list(self): class MyDoc(SchemaDocument): structure = { "foo":{str:[int]} } mydoc = MyDoc() mydoc['foo'] = {"bar":[1,2,3]} mydoc.validate() mydoc['foo'] = {"bar":["bla"]} self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo'] = {3:[1,2,3]} self.assertRaises(SchemaTypeError, mydoc.validate) def test_with_custom_object(self): class MyDict(dict): pass class MyDoc(SchemaDocument): structure = { "foo":{str:int} } mydoc = MyDoc() mydict = MyDict() mydict["foo"] = 3 mydoc["foo"] = mydict mydoc.validate() def test_custom_object_as_type(self): class MyDict(dict): pass class MyDoc(SchemaDocument): structure = { "foo":MyDict({str:int}) } mydoc = MyDoc() mydict = MyDict() mydict["foo"] = 3 mydoc["foo"] = mydict mydoc.validate() mydoc['foo'] = {"foo":"7"} self.assertRaises(SchemaTypeError, mydoc.validate) class MyInt(int): pass class MyDoc(SchemaDocument): structure = { "foo":MyInt, } mydoc = MyDoc() mydoc["foo"] = MyInt(3) mydoc.validate() mydoc['foo'] = 3 self.assertRaises(SchemaTypeError, mydoc.validate) def test_list_instead_of_dict(self): class MyDoc(SchemaDocument): structure = { "foo":{str:[str]} } mydoc = MyDoc() mydoc['foo'] = ['bla'] self.assertRaises(SchemaTypeError, mydoc.validate) def _test_big_nested_example(self): # XXX TODO class MyDoc(SchemaDocument): structure = { "foo":{str:[int], "bar":{"spam":{int:[str]}}}, "bla":{"blo":{"bli":[{"arf":str}]}}, } mydoc = MyDoc() mydoc['foo'].update({"bir":[1,2,3]}) mydoc['foo']['bar']['spam'] = {1:['bla', 'ble'], 3:['foo', 'bar']} mydoc.validate() mydoc['bla']['blo']['bli'] = [{"bar":["bla"]}] self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['bla']['blo']['bli'] = [{"arf":[1]}] self.assertRaises(SchemaTypeError, mydoc.validate) def test_adding_custom_type(self): class MyDoc(SchemaDocument): structure = { "foo":str, } authorized_types = SchemaDocument.authorized_types + [str] mydoc = MyDoc() def test_schema_operator(self): from mongokit.operators import SchemaOperator class OP(SchemaOperator): repr = "op" op = OP() self.assertRaises(NotImplementedError, op.validate, "bla") def test_or_operator(self): from mongokit import OR assert repr(OR(int, str)) == "<int or str>" failed = False try: class BadMyDoc(SchemaDocument): structure = {"bla":OR(int, tuple)} except StructureError as e: self.assertEqual(str(e), "BadMyDoc: <%s 'tuple'> in <int or tuple> is not an authorized type (type found)" % ('type' if six.PY2 else 'class')) failed = True self.assertEqual(failed, True) from datetime import datetime class MyDoc(SchemaDocument): structure = { "foo":OR(str,int), "bar":OR(str, datetime) } mydoc = MyDoc() assert str(mydoc.structure['foo']) == '<%s or int>' % str.__name__ assert str(mydoc.structure['bar']) == '<%s or datetime>' % str.__name__ assert mydoc == {'foo': None, 'bar': None} mydoc['foo'] = 3.0 self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo'] = "foo" mydoc.validate() mydoc['foo'] = 3 mydoc.validate() mydoc['foo'] = six.b('bar') self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo'] = datetime.now() self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo'] = "foo" mydoc['bar'] = datetime.now() mydoc.validate() mydoc['bar'] = "today" mydoc.validate() mydoc['bar'] = 25 self.assertRaises(SchemaTypeError, mydoc.validate) def test_not_operator(self): from mongokit import NOT failed = False try: class BadMyDoc(SchemaDocument): structure = {"bla":NOT(int, tuple)} except StructureError as e: self.assertEqual(str(e), "BadMyDoc: <%s 'tuple'> in <not int, not tuple> is not an authorized type (type found)" % ('type' if six.PY2 else 'class')) failed = True self.assertEqual(failed, True) from datetime import datetime class MyDoc(SchemaDocument): structure = { "foo":NOT(str,int), "bar":NOT(datetime) } mydoc = MyDoc() assert str(mydoc.structure['foo']) == '<not %s, not int>' % str.__name__, str(mydoc.structure['foo']) assert str(mydoc.structure['bar']) == '<not datetime>' assert mydoc == {'foo': None, 'bar': None} assert mydoc['foo'] is None assert mydoc['bar'] is None mydoc['foo'] = 3 self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo'] = "foo" self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo'] = 3.0 mydoc.validate() mydoc['foo'] = datetime.now() mydoc.validate() mydoc['bar'] = datetime.now() self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['bar'] = "today" mydoc.validate() mydoc['bar'] = 25 mydoc.validate() def test_is_operator(self): from mongokit import IS failed = False try: class BadMyDoc(SchemaDocument): structure = {"bla":IS(('bla',),3)} except StructureError as e: self.assertEqual(str(e), "BadMyDoc: ('bla',) in <is ('bla',) or is 3> is not an authorized type (tuple found)") failed = True self.assertEqual(failed, True) from datetime import datetime class MyDoc(SchemaDocument): structure = { "foo":IS('spam','eggs'), "bar":IS('3', 3) } mydoc = MyDoc() assert str(mydoc.structure['foo']) == "<is 'spam' or is 'eggs'>" assert str(mydoc.structure['bar']) == "<is '3' or is 3>" assert mydoc == {'foo': None, 'bar': None} assert mydoc['foo'] is None assert mydoc['bar'] is None mydoc['foo'] = 3 self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo'] = "bla" self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo'] = datetime.now() self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo'] = "spam" mydoc.validate() mydoc['foo'] = "eggs" mydoc.validate() mydoc['bar'] = datetime.now() self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['bar'] = "today" self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['bar'] = 'foo' self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['bar'] = 3 mydoc.validate() mydoc['bar'] = "3" mydoc.validate() def test_subclassed_type(self): """ accept all subclass of supported type """ class CustomFloat(float): def __init__(self, float): self = float + 2 class MyDoc(SchemaDocument): structure = { "foo":float, } mydoc = MyDoc() mydoc['foo'] = CustomFloat(4) mydoc.validate() def test_set_type(self): from mongokit import Set class MyDoc(Document): structure = { "tags":Set(int), } self.connection.register([MyDoc]) mydoc = self.col.MyDoc() mydoc['tags'] = set(["1","1","2","3","4"]) self.assertRaises(ValueError, mydoc.validate) mydoc['tags'] = set([1,1,2,3,4]) mydoc.save() doc = self.col.MyDoc.find_one() assert doc['tags'] == set([1,2,3,4]), doc['tags'] def test_set_type2(self): class MyDoc(Document): structure = { 'title':str, 'category':Set(str) } required_fields=['title'] self.connection.register([MyDoc]) doc = self.col.MyDoc() print(doc) # {'category': set([]), 'title': None} assert isinstance(doc['category'], set) try: doc.validate() except RequireFieldError as e: print(e) # title is required print(doc) # {'category': [], 'title': None} assert isinstance(doc['category'], set) doc['title']='hello' doc.validate() def test_int_type(self): @self.connection.register class MyDoc(Document): structure = { "foo":int, } mydoc = self.col.MyDoc() mydoc['foo'] = '' self.assertRaises(SchemaTypeError, mydoc.validate) mydoc['foo'] = 10 mydoc.save() def test_uuid_type(self): import uuid @self.connection.register class MyDoc(Document): structure = { 'uuid': uuid.UUID, } uid = uuid.uuid4() obj = self.col.MyDoc() obj['uuid'] = uid obj.save() assert isinstance(self.col.MyDoc.find_one()['uuid'], uuid.UUID) def test_binary_with_bytes_type(self): import bson @self.connection.register class MyDoc(Document): structure = { 'my_binary': bytes, } obj = self.col.MyDoc() # non-utf8 string non_utf8 = b"\xFF\xFE\xFF"; obj['my_binary'] = non_utf8 obj.save() self.assertEquals(self.col.MyDoc.find_one()['my_binary'], non_utf8) def test_binary_with_binary_type(self): import bson @self.connection.register class MyDoc(Document): structure = { 'my_binary': bson.binary.Binary, } obj = self.col.MyDoc() # non-utf8 string non_utf8 = b"\xFF\xFE\xFF"; bin_obj = bson.binary.Binary(non_utf8) obj['my_binary'] = bin_obj obj.save() self.assertEquals(self.col.MyDoc.find_one()['my_binary'], non_utf8)
class Database(object): """The database connection""" @staticmethod def get_db(): """Return the database based on DATABASE_URI env var :rtype: Database """ if 'DATABASE_URI' in os.environ: uri = os.environ['DATABASE_URI'] return Database(uri=uri) raise EnvironmentError('DATABASE_URI environment variable is missing') def __init__(self, uri): """Init the Database using given uri :param uri: The URI to connect to, such as mongodb://LOGIN:PASSWORD@SERVER:PORT/DB_NAME """ self.uri = uri self.connect(uri) self.dbname = uri.split('/')[-1] logging.info('dbname is %s', self.dbname) def connect(self, uri): """Connect to given uri :param uri: The URI to connect to, such as mongodb://LOGIN:PASSWORD@SERVER:PORT/DB_NAME """ logging.info('Connecting to uri %s', uri) self.connection = Connection(host=uri) self.connection.register([User, Play]) return self.connection # pylint: disable=C0103 @property def db(self): """Return the pymongo's db object using the database name""" return self.connection[self.dbname] def add_user(self, login, name, passwd, email): """Add a user :param login: The user login :param name: The user complete name :param passwd: The user password, will be hashed :param email: The user email""" # must not already exist if self.get_user(login=login): msg = 'A user with login "%s" has already been declared' % login raise ValueError(msg) user = self.db.User() user['login'] = login user['name'] = name user['email'] = email user['passwd'] = hash_password(passwd) user.save() def delete_user(self, login): """Delete the user with the given login""" user = self.get_user(login=login) if user: user.delete() def drop(self): """Drop the database""" self.connection.drop_database(self.dbname) # pylint: disable=R0201 def authenticate_user(self, user, passwd): """Authenticate the user """ hashed_passwd = hash_password(passwd) user.authauthenticate(hashed_passwd) def get_user(self, login): """Retrieve the user with given login or None""" return self.db.User.one({'login': login}) def add_play(self, date, game, creator): """Add a play :type date: datetime.datetime :type game: basestring :rtype: Play""" play = self.db.Play() play.set_date(date) play.set_game(game) play.set_created_by(creator) play.save() return play def add_play_from_json(self, json_play): """Adds a play from a json definition :type json_play: dict|basestring :rtype: Play""" # TODO: improve typecheck if type(json_play) == dict: json_play = json.dumps(json_play) play = self.db.Play.from_json(json_play) play.save() return play def get_plays(self): """Return all plays""" return [play for play in self.db.Play.find()] def migrate_all(self): """Runs the migration rules in bulk""" migration_play = PlayMigration(Play) migration_play.migrate_all(self.db.plays) # pylint: disable=E1101 def dump(self, dump_folder=None): """Dump the database in the given dump_file Use the archive option to compress if uri is None, will use DATABASE_URI env var if dump_folder is None, will use a timetagged folder""" logging.info('mongodumping') info = Database.get_uri_info(uri=self.uri) if dump_folder is None: timetag = datetime.datetime.now().strftime('%y%m%d_%H%M%S') dump_foldername = '{}_{}'.format(timetag, info['db_name']) dump_folder = os.path.join('dump', dump_foldername) info['dump_folder'] = dump_folder info['temp_folder'] = tempfile.mkdtemp() logging.info('mongodump on %s', info) cmd = '' \ 'mongodump -h {host} --port {port} -u {user} -p {password}' \ ' --db {db_name} --out={temp_folder}'.format(**info) logging.info(cmd) if dump_folder != '' and not os.path.exists(dump_folder): os.makedirs(dump_folder) rcode = subprocess.call(cmd.split(' ')) if rcode == 0: logging.info('dumped to %s', dump_folder) os.rename(os.path.join(info['temp_folder'], info['db_name']), dump_folder) else: logging.fatal('Failed to dump! - return code is %s', rcode) def restore(self, dump_folder, delete=False): """Restore a dump saved using mongodump in the given database""" logging.info('mongorestoring') if not os.path.exists(dump_folder): raise RuntimeError('dump folder does not exist %s' % dump_folder) info = Database.get_uri_info(uri=self.uri) info['dump_folder'] = dump_folder logging.info('mongorestore on %s', info) if delete: self.drop() cmd = '' \ 'mongorestore -h {host} --port {port} -u {user} -p {password}' \ ' --db {db_name} {dump_folder}'.format(**info) logging.info(cmd) rcode = subprocess.call(cmd.split(' ')) if rcode == 0: logging.info('restored from %s', dump_folder) else: logging.fatal('Failed to restore! - return code is %s', rcode) @staticmethod def get_uri_info(uri): """Return configured UriInfo (host, port, username, password, dbname) based on the configured DATABASE_URI env var :rtype: tuple """ if uri is None and 'DATABASE_URI' not in os.environ: msg = 'Must give uri or have os.environ[\'DATABASE_URI\']' raise RuntimeError(msg) elif uri is None: uri = os.environ['DATABASE_URI'] return Database.parse_uri(uri) @staticmethod def parse_uri(uri): """Return the elements of the uri: (host, port, username, password, dbname) """ match = re.match((r'mongodb://(?P<user>[^:]+):(?P<password>[^@]+)' r'@(?P<host>[^:]+):(?P<port>\d+)/(?P<db_name>\w+)'), uri) if match: return { 'host': match.group('host'), 'port': match.group('port'), 'user': match.group('user'), 'password': match.group('password'), 'db_name': match.group('db_name') } raise RuntimeError('Failed to parse uri: {}'.format(uri))