def get_document(self, document_class, _id, *, exc=None, read_preference=RPS.PrimaryPreferred(), **collection_params): """ Get document for it _id. :param document_class: :class:`yadm.documents.Document` :param _id: document's _id :param Exception exc: raise given exception if not found :param **collection_params: params for get_collection Default ReadPreference is PrimaryPreferred. """ collection_params['read_preference'] = read_preference col = self.db.get_collection(document_class.__collection__, **collection_params) raw = col.find_one({'_id': _id}) if raw: doc = from_mongo(document_class, raw) doc.__db__ = self return doc elif exc is not None: raise exc((document_class, _id, collection_params)) else: return None
def _from_mongo_one(self, data, *, projection=None): """ Create document from raw data. """ projection = projection or self._projection if data is None: # pragma: no cover return None elif not projection: not_loaded = frozenset() else: include = [f for f, v in projection.items() if v] exclude = {f for f, v in projection.items() if not v} if include: if exclude and exclude != {'_id'}: # pragma: no cover raise ValueError("projection cannot have a mix" " of inclusion and exclusion") for field_name in self._document_class.__fields__: if field_name not in include and field_name != '_id': exclude.add(field_name) not_loaded = exclude doc = from_mongo(self._document_class, data, not_loaded) doc.__db__ = self._db doc.__qs__ = self return doc
def _from_mongo_one(self, data, *, projection=None): """ Create document from raw data. """ projection = projection or self._projection if data is None: return None elif not projection: not_loaded = () else: include = [f for f, v in projection.items() if v] exclude = {f for f, v in projection.items() if not v} if include: if exclude and exclude != {'_id'}: raise ValueError("projection cannot have a mix" " of inclusion and exclusion") for field_name in self._document_class.__fields__: if field_name not in include: exclude.add(field_name) not_loaded = exclude doc = from_mongo(self._document_class, data, not_loaded) doc.__db__ = self._db doc.__qs__ = self return doc
def get_document(self, document_class, _id, *, projection=None, exc=None, read_preference=RPS.PrimaryPreferred(), **collection_params): """ Get document for it _id. Default ReadPreference is PrimaryPreferred. """ collection_params['read_preference'] = read_preference col = self.db.get_collection(document_class.__collection__, **collection_params) if projection is None: projection = document_class.__default_projection__ if projection is not None: raw = col.find_one({'_id': _id}, projection) not_loaded = [k for k, v in projection.items() if not v] else: raw = col.find_one({'_id': _id}) not_loaded = [] if raw: doc = from_mongo(document_class, raw, not_loaded=not_loaded) doc.__db__ = self return doc elif exc is not None: raise exc((document_class, _id, collection_params)) else: return None
async def get_document(self, document_class, _id, *, projection=None, exc=None, read_preference=RPS.PrimaryPreferred(), **collection_params): collection_params['read_preference'] = read_preference col = self.db.get_collection(document_class.__collection__, **collection_params) if projection is None: projection = document_class.__default_projection__ if projection is not None: raw = await col.find_one({'_id': _id}, projection) not_loaded = [k for k, v in projection.items() if not v] else: raw = await col.find_one({'_id': _id}) not_loaded = [] if raw: doc = from_mongo(document_class, raw, not_loaded=not_loaded) doc.__db__ = self return doc elif exc is not None: raise exc((document_class, _id, collection_params)) else: return None
def test_update_one__push_pull(db, cmd, v, r): col = db.db.testdocs _id = col.insert({'l': [1, 2, 3]}) doc = from_mongo(Doc, col.find_one(_id)) db.update_one(doc, **{cmd: {'l': v}}) assert doc.l == r
def test_remove(db): col = db.db.testdocs col.insert({'i': 13}) doc = from_mongo(Doc, col.find_one({'i': 13})) assert col.count() == 1 db.remove(doc) assert col.count() == 0
async def test(): col = db.db['testdocs'] await col.insert_one({'i': 13}) doc = from_mongo(Doc, await col.find_one({'i': 13})) assert await col.count_documents({}) == 1 await db.delete_one(doc) assert await col.count_documents({}) == 0
def test_remove(self): col = self.db.db.testdocs col.insert({'i': 13}) td = from_mongo(self.TestDoc, col.find_one({'i': 13})) self.assertEqual(col.count(), 1) self.db.remove(td) self.assertEqual(col.count(), 0)
async def test(): col = db.db.testdocs await col.insert({'i': 13}) doc = from_mongo(Doc, await col.find_one({'i': 13})) assert await col.count() == 1 await db.remove(doc) assert await col.count() == 0
def test_from__smart_null(): class Doc(Document): i = fields.IntegerField(smart_null=True) s = fields.StringField() doc = from_mongo(Doc, {'s': 'string'}) assert doc.s == 'string' assert doc.i is None
def _from_mongo_one(self, data): """ Create document from raw data """ if data is not None: doc = from_mongo(self._document_class, data) doc.__db__ = self._db return doc else: return None
def test_delete_one(db): col = db.db['testdocs'] col.insert_one({'i': 13}) doc = from_mongo(Doc, col.find_one({'i': 13})) assert col.count_documents({}) == 1 db.delete_one(doc) assert col.count_documents({}) == 0
def test_update_one(db, unset): col = db.db.testdocs _id = col.insert({'i': 13}) doc = from_mongo(Doc, col.find_one(_id)) db.update_one(doc, set={'b': True}, unset=unset) assert doc.b assert not hasattr(doc, 'i')
def test_update_one__inc(db): col = db.db.testdocs _id = col.insert({'i': 12}) doc = from_mongo(Doc, col.find_one(_id)) db.update_one(doc, inc={'i': 1}) assert doc.i == 13 assert not hasattr(doc, 'b')
def from_mongo(self, document, value): if value is None: return None elif not isinstance(value, self.embedded_document_class): value = from_mongo(self.embedded_document_class, value, clear_fields_changed=True) value.__parent__ = document value.__name__ = self.name return value
def test_serialize_cycle(self, db): doc = self.Doc() doc.money = fields.Money(1, 'RUB') db.save(doc) data = db(self.Doc).find_one() data_tm = to_mongo(data) assert data_tm['money'][0] == 100 assert data_tm['money'][1] == 643 data_fm = from_mongo(self.Doc, data_tm) assert data_fm.money == fields.Money(1, 'RUB')
def test_save(self): col = self.db.db.testdocs col.insert({'i': 13}) td = from_mongo(self.TestDoc, col.find_one({'i': 13})) td.i = 26 self.db.save(td) self.assertEqual(self.db.db.testdocs.find().count(), 1) self.assertEqual(self.db.db.testdocs.find()[0]['i'], 26) self.assertFalse(td.__fields_changed__) self.assertIs(td.__db__, self.db)
def from_mongo(self, document, value): ed_class = self.get_embedded_document_class(document, value) not_loaded = set() if getattr(document, '__not_loaded__', None): _sw = self.name + '.' for field_name in document.__not_loaded__: if field_name.startswith(_sw): not_loaded.add(field_name[len(_sw):]) return from_mongo(ed_class, value, not_loaded=not_loaded, parent=document, name=self.name)
def test_save(db): col = db.db['testdocs'] col.insert_one({'i': 13}) doc = from_mongo(Doc, col.find_one({'i': 13})) doc.i = 26 col.update_one({'_id': doc.id}, {'$set': {'b': True}}) db.save(doc) assert doc.i == 26 assert not hasattr(doc, 'b') assert db.db['testdocs'].count_documents({}) == 1 assert db.db['testdocs'].find()[0]['i'] == 26 assert Save(id=doc.id) in doc.__log__ assert doc.__db__ is db
def test_from__simple(): raw = { 'i': 1, 's': 'string', 'e': { 'ii': 2, 'ss': 'stringstring', }, } doc = from_mongo(Doc, raw) assert isinstance(doc, Doc) assert doc.i == raw['i'] assert doc.s == raw['s'] assert isinstance(doc.e, EDoc) assert doc.e.ii == raw['e']['ii'] assert doc.e.ss == raw['e']['ss']
def test_save_full(db): col = db.db.testdocs col.insert({'i': 13}) doc = from_mongo(Doc, col.find_one({'i': 13})) doc.i = 26 col.update({'_id': doc.id}, {'$set': {'b': True}}) db.save(doc, full=True) assert doc.i == 26 assert not hasattr(doc, 'b') assert db.db.testdocs.find().count() == 1 assert db.db.testdocs.find()[0]['i'] == 26 assert 'b' not in db.db.testdocs.find()[0] assert not doc.__changed__ assert doc.__db__ is db
def test_from__not_loaded(): raw = { 'i': 1, 's': 'string', 'e': { 'ii': 2, 'ss': 'stringstring', }, } doc = from_mongo(Doc, raw, not_loaded=['s', 'e.ii']) assert isinstance(doc, Doc) assert doc.i == raw['i'] assert doc.__not_loaded__ == frozenset({'s', 'e.ii'}) assert isinstance(doc.e, EDoc) assert doc.e.ss == raw['e']['ss'] assert doc.e.__not_loaded__ == frozenset({'ii'})
def test_save(db): col = db.db.testdocs col.insert({'i': 13}) doc = from_mongo(Doc, col.find_one({'i': 13})) doc.i = 26 col.update({'_id': doc.id}, {'$set': {'b': True}}) db.save(doc) assert doc.i == 26 assert doc.b is True assert db.db.testdocs.find().count() == 1 assert db.db.testdocs.find()[0]['i'] == 26 assert db.db.testdocs.find()[0]['b'] is True assert not doc.__changed__ assert doc.__db__ is db
def from_mongo(self, document, value): """ Resolve reference. 1. Lookup in querysets cache; 2. Lookup in __yadm_lookups__[self.name]; 3. Lookup in database; 4. Raise BrokenReference if not found. """ rdc = self.reference_document_class if document.__qs__ is not None: cache = document.__qs__.cache else: cache = {} # fake cache if (rdc, value) in cache: return cache[(rdc, value)] elif (isinstance(document, Document) and self.name in document.__yadm_lookups__): cache[(rdc, value)] = doc = from_mongo( document_class=rdc, raw=document.__yadm_lookups__[self.name], ) doc.__db__ = document.__db__ return doc elif document.__db__ is not None: if document.__db__.aio: cache[(rdc, value)] = ref = Reference(value, document, self) return ref else: qs = document.__db__.get_queryset(rdc, cache=cache) doc = qs.find_one(value) if doc is None: # pragma: no cover doc = qs.read_primary().find_one(value, exc=BrokenReference) cache[(rdc, value)] = doc return doc else: raise NotBindingToDatabase((document, self, value))
def from_mongo(self, document, value): from yadm.documents import Document # recursive imports if isinstance(value, (ObjectId, str)): if document.__db__ is not None: qs = document.__db__.get_queryset(self.reference_document_class) doc = qs.with_id(value) return doc if doc else ObjectId(value) else: return value elif isinstance(value, dict): return from_mongo(self.reference_document_class, value) elif isinstance(value, Document): return value else: raise TypeError('value must be ObjectId, Document or dict')
def from_mongo(self, document, value): from yadm.documents import Document # recursive imports if isinstance(value, (ObjectId, str)): if document.__db__ is not None: qs = document.__db__.get_queryset( self.reference_document_class) doc = qs.with_id(value) return doc if doc else ObjectId(value) else: return value elif isinstance(value, dict): return from_mongo(self.reference_document_class, value) elif isinstance(value, Document): return value else: raise TypeError('value must be ObjectId, Document or dict')
async def get_document(self, document_class, _id, *, exc=None, read_preference=RPS.PrimaryPreferred(), **collection_params): collection_params['read_preference'] = read_preference col = self.db.get_collection(document_class.__collection__, **collection_params) raw = await col.find_one({'_id': _id}) if raw: doc = from_mongo(document_class, raw) doc.__db__ = self return doc elif exc is not None: raise exc((document_class, _id, collection_params)) else: return None
def from_mongo(self, document, value): if value is None: return None elif isinstance(value, dict): return from_mongo(self.reference_document_class, value) elif isinstance(value, Document): return value else: if document.__db__ is not None: qs = document.__db__.get_queryset(self.reference_document_class) doc = qs.with_id(value) if doc: return doc else: field = self.reference_document_class.__fields__['_id'] return field.prepare_value(None, value) else: return value
def from_mongo(self, document, value): ed_class = self.get_embedded_document_class(document, value) return from_mongo(ed_class, value, parent=document, name=self.name)
def from_mongo(self, document, value): value = from_mongo(self.embedded_document_class, value, parent=document, name=self.name) return value
def document(self): if self._document_cache is None: document_class = self._bulk._document_class self._document_cache = from_mongo(document_class, self.op) return self._document_cache