def get_next_id(col: pymongo.collection.Collection, id_name: str): # logger.warning(f'id_name: {id_name}') ret = col.find_one_and_update({"_id": id_name}, {"$inc": {"sequence_value": 1}}, new=True) new_id = ret["sequence_value"] return new_id
def update_user_document(coll: pymongo.collection.Collection, user_id: ObjectId, document_id: ObjectId, document: dict): assert isinstance(user_id, ObjectId) assert isinstance(document_id, ObjectId) to_set, to_unset = get_mdocument_set_unset_dicts(document) operation_dict = {} if to_set: # některý z fieldů je neprázdný operation_dict["$set"] = { f"documents.$.{key}": value for key, value in to_set.items() } if to_unset: operation_dict["$unset"] = { f"documents.$.{key}": value for key, value in to_unset.items() } assert not (set(to_set.keys()).intersection(set(to_unset.keys()))) print("to_set", to_set) print("to_unset", to_unset) updated = coll.find_one_and_update( { "_id": user_id, "documents._id": document_id }, operation_dict, return_document=ReturnDocument.AFTER) if not list(updated): raise ValueError("Uživatel nemá dokument s tímto _id")
def import_new_records(base_id: str, table: str, mongo_table: pymongo.collection.Collection, view: Optional[str] = None) -> None: """Import new records from Airtable to MongoDB.""" if not _AIRTABLE_API_KEY: raise ValueError( 'No API key found. Create an airtable API key at ' 'https://airtable.com/account and set it in the AIRTABLE_API_KEY ' 'env var.') client = airtable.Airtable(base_id, _AIRTABLE_API_KEY) records = client.iterate(table, view=view) converter = airtable_to_protos.ProtoAirtableConverter( proto_type=review_pb2.DocumentToReview, id_field=None, required_fields=('anonymized_url', )) num_inserted = 0 num_updated = 0 for record in records: mongo_id = record.get('fields', {}).get('mongo_id') proto_data = converter.convert_record(record) airtable_id = proto_data.pop('_id') if record['fields'].get('anonymized_url'): proto_data['anonymizedUrl'] = record['fields']['anonymized_url'][ 0]['url'] if mongo_id: # Already added, let's update it. document_json = mongo_table.find_one_and_update( {'_id': objectid.ObjectId(mongo_id)}, {'$set': proto_data}, ) any_pending_or_done_review = document_json.get('numPendingReviews', 0) or \ document_json.get('numDoneReviews', 0) timeout_review_count = sum( 1 for review in document_json.get('reviews', []) if review.get('status') == 'REVIEW_TIME_OUT') client.update( table, airtable_id, { 'Bayes help needed': not any_pending_or_done_review, 'review_timeouts': timeout_review_count, }) num_updated += 1 continue result = mongo_table.insert_one(proto_data) mongo_id = str(result.inserted_id) client.update(table, airtable_id, { 'mongo_id': mongo_id, 'Bayes help needed': True }) num_inserted += 1 print(f'{num_updated:d} documents updated.') print(f'{num_inserted:d} documents added.')
def update_user_address(coll: pymongo.collection.Collection, user_id: ObjectId, address: dict): assert isinstance(user_id, ObjectId) address_type = address["type"] to_set, to_unset = get_mdocument_set_unset_dicts(address) # pokud už je tento typ adresy v databázi if coll.find_one({"_id": user_id, "addresses.type": address_type}): operation_dict = {} if len(to_set) > 1: # je tam něco kromě "type" operation_dict["$set"] = { f"addresses.$.{key}": value for key, value in to_set.items() } if to_unset: operation_dict["$unset"] = { f"addresses.$.{key}": value for key, value in to_unset.items() } updated = coll.find_one_and_update( { "_id": user_id, "addresses.type": address_type }, operation_dict, return_document=ReturnDocument.AFTER) # smaž adresu z "addresses", pokud po updatu obsahuje pouze "type" for address in updated["addresses"]: if address["type"] == address_type and len(address) <= 1: delete_user_address(coll, user_id, address_type) # jinak přidej adresu do databáze, pokud obsahuje víc než jen "type" elif len(address) > 1: add_embedded_mdoc_to_mdoc_array(coll, user_id, "addresses", address, filter_values=None)
def update_user(coll: pymongo.collection.Collection, user_id: ObjectId, data: dict, embedded_1to1_docs=("name", )): assert isinstance(user_id, ObjectId) to_unset = {key: "" for key, value in data.items() if value == ""} for key in to_unset: del data[key] operation_dict = {} if data: operation_dict["$set"] = data if to_unset: operation_dict["$unset"] = to_unset updated = coll.find_one_and_update({"_id": user_id}, operation_dict, return_document=ReturnDocument.AFTER) for key in embedded_1to1_docs: if key in updated and not updated[key]: coll.update_one({"_id": user_id}, {"$unset": {"name": ""}})