11# -*- coding: utf-8 -*-
22from __future__ import absolute_import
33
4- from flask import abort
4+ from flask import abort , current_app
55
66import mongoengine
77
88from mongoengine .queryset import MultipleObjectsReturned , DoesNotExist , QuerySet
99from mongoengine .base import ValidationError
1010
11+ from pymongo import uri_parser
12+
1113from .sessions import *
1214from .pagination import *
1315from .json import overide_json_encoder
@@ -20,55 +22,81 @@ def _include_mongoengine(obj):
2022 setattr (obj , key , getattr (module , key ))
2123
2224
25+ def _create_connection (conn_settings ):
26+
27+ # Handle multiple connections recursively
28+ if isinstance (conn_settings , list ):
29+ connections = {}
30+ for conn in conn_settings :
31+ connections [conn .get ('alias' )] = _create_connection (conn )
32+ return connections
33+
34+ conn = dict ([(k .lower (), v ) for k , v in conn_settings .items () if v ])
35+
36+ if 'replicaset' in conn :
37+ conn ['replicaSet' ] = conn .pop ('replicaset' )
38+
39+ # Handle uri style connections
40+ if "://" in conn .get ('host' , '' ):
41+ uri_dict = uri_parser .parse_uri (conn_settings ['host' ])
42+ conn ['db' ] = uri_dict ['database' ]
43+
44+ return mongoengine .connect (conn .pop ('db' , 'test' ), ** conn )
45+
46+
2347class MongoEngine (object ):
2448
25- def __init__ (self , app = None ):
49+ def __init__ (self , app = None , config = None ):
2650
2751 _include_mongoengine (self )
2852
2953 self .Document = Document
3054 self .DynamicDocument = DynamicDocument
3155
3256 if app is not None :
33- self .init_app (app )
57+ self .init_app (app , config )
3458
35- def init_app (self , app ):
59+ def init_app (self , app , config = None ):
3660
37- conn_settings = app . config . get ( 'MONGODB_SETTINGS ' , None )
61+ app . extensions = getattr ( app , 'extensions ' , {} )
3862
39- if not conn_settings :
40- conn_settings = {
41- 'db' : app .config .get ('MONGODB_DB' , None ),
42- 'username' : app .config .get ('MONGODB_USERNAME' , None ),
43- 'password' : app .config .get ('MONGODB_PASSWORD' , None ),
44- 'host' : app .config .get ('MONGODB_HOST' , None ),
45- 'port' : int (app .config .get ('MONGODB_PORT' , 0 )) or None
46- }
63+ # Make documents JSON serializable
64+ overide_json_encoder (app )
4765
48- if isinstance (conn_settings , list ):
49- self .connection = {}
50- for conn in conn_settings :
51- conn = dict ((k .lower (), v ) for k , v in conn .items () if v is not None )
66+ if not 'mongoengine' in app .extensions :
67+ app .extensions ['mongoengine' ] = {}
5268
53- if 'replicaset' in conn :
54- conn ['replicaSet' ] = conn ['replicaset' ]
55- del conn ['replicaset' ]
69+ if self in app .extensions ['mongoengine' ]:
70+ # Raise an exception if extension already initialized as
71+ # potentially new configuration would not be loaded.
72+ raise Exception ('Extension already initialized' )
5673
57- self .connection [conn .get ('alias' )] = mongoengine .connect (** conn )
74+ if not config :
75+ # If not passed a config then we read the connection settings
76+ # from the app config.
77+ config = app .config
5878
79+ if 'MONGODB_SETTINGS' in config :
80+ # Connection settings provided as a dictionary.
81+ connection = _create_connection (config ['MONGODB_SETTINGS' ])
5982 else :
60- conn_settings = dict ([(k .lower (), v ) for k , v in conn_settings .items () if v ])
61-
62- if 'replicaset' in conn_settings :
63- conn_settings ['replicaSet' ] = conn_settings ['replicaset' ]
64- del conn_settings ['replicaset' ]
65-
66- self .connection = mongoengine .connect (** conn_settings )
67-
68- app .extensions = getattr (app , 'extensions' , {})
69- app .extensions ['mongoengine' ] = self
70- self .app = app
71- overide_json_encoder (app )
83+ # Connection settings provided in standard format.
84+ settings = {'alias' : config .get ('MONGODB_ALIAS' , None ),
85+ 'db' : config .get ('MONGODB_DB' , None ),
86+ 'host' : config .get ('MONGODB_HOST' , None ),
87+ 'password' : config .get ('MONGODB_PASSWORD' , None ),
88+ 'port' : config .get ('MONGODB_PORT' , None ),
89+ 'username' : config .get ('MONGODB_USERNAME' , None )}
90+ connection = _create_connection (settings )
91+
92+ # Store objects in application instance so that multiple apps do
93+ # not end up accessing the same objects.
94+ app .extensions ['mongoengine' ][self ] = {'app' : app ,
95+ 'conn' : connection }
96+
97+ @property
98+ def connection (self ):
99+ return current_app .extensions ['mongoengine' ][self ]['conn' ]
72100
73101
74102class BaseQuerySet (QuerySet ):
0 commit comments