def _do_migration(self, doc): attachments = doc.pop("_attachments") external_blobs = doc.setdefault("external_blobs", {}) obj = BlobHelper(doc, self.couchdb) try: with obj.atomic_blobs(): for name, data in list(attachments.iteritems()): if name in external_blobs: continue # skip attachment already in blob db obj.put_attachment(name=name, **data) except ResourceConflict: # Do not migrate document if `atomic_blobs()` fails. # This is an unlikely state, but could happen if the # document is (externally) modified between when the # migration fetches and processes the document. return False return True
def migrate(self, doc, couchdb): attachments = doc.pop("_attachments") external_blobs = doc.setdefault("external_blobs", {}) obj = BlobHelper(doc, couchdb) try: with obj.atomic_blobs(): for name, data in list(attachments.iteritems()): if name in external_blobs: continue # skip attachment already in blob db obj.put_attachment(name=name, **data) except ResourceConflict: # Do not migrate document if `atomic_blobs()` fails. # This is an unlikely state, but could happen if the # document is (externally) modified between when the # migration fetches and processes the document. return False return True
def save(transform, database): # this is a fancy save method because we do some special casing # with the attachments and with deleted documents def save(): try: database.save_doc(transform.doc, force_update=True) except ResourceNotFound: # this is likely a document that was deleted locally that # you later want to copy back over there is a wacky hack # that you can use to handle this rev = get_deleted_doc_rev(database, transform.doc['_id']) transform.doc['_rev'] = rev database.save_doc(transform.doc) if transform.attachments: obj = BlobHelper(transform.doc, database) with obj.atomic_blobs(save): for name, attach in transform.attachments.items(): content_type = transform._attachments[name]["content_type"] obj.put_attachment(attach, name, content_type=content_type) else: save()