mirror of
https://github.com/arc53/DocsGPT.git
synced 2025-11-29 00:23:17 +00:00
Fixes shared conversation on cloud version (#2135)
* (fix:shared) conv as id, not dbref * (chore) script to migrate dbref to id * (chore): ruff fix --------- Co-authored-by: GH Action - Upstream Sync <action@github.com>
This commit is contained in:
@@ -13,7 +13,6 @@ from application.api.user.base import (
|
|||||||
agents_collection,
|
agents_collection,
|
||||||
attachments_collection,
|
attachments_collection,
|
||||||
conversations_collection,
|
conversations_collection,
|
||||||
db,
|
|
||||||
shared_conversations_collections,
|
shared_conversations_collections,
|
||||||
)
|
)
|
||||||
from application.utils import check_required_fields
|
from application.utils import check_required_fields
|
||||||
@@ -97,9 +96,7 @@ class ShareConversation(Resource):
|
|||||||
api_uuid = pre_existing_api_document["key"]
|
api_uuid = pre_existing_api_document["key"]
|
||||||
pre_existing = shared_conversations_collections.find_one(
|
pre_existing = shared_conversations_collections.find_one(
|
||||||
{
|
{
|
||||||
"conversation_id": DBRef(
|
"conversation_id": ObjectId(conversation_id),
|
||||||
"conversations", ObjectId(conversation_id)
|
|
||||||
),
|
|
||||||
"isPromptable": is_promptable,
|
"isPromptable": is_promptable,
|
||||||
"first_n_queries": current_n_queries,
|
"first_n_queries": current_n_queries,
|
||||||
"user": user,
|
"user": user,
|
||||||
@@ -120,10 +117,7 @@ class ShareConversation(Resource):
|
|||||||
shared_conversations_collections.insert_one(
|
shared_conversations_collections.insert_one(
|
||||||
{
|
{
|
||||||
"uuid": explicit_binary,
|
"uuid": explicit_binary,
|
||||||
"conversation_id": {
|
"conversation_id": ObjectId(conversation_id),
|
||||||
"$ref": "conversations",
|
|
||||||
"$id": ObjectId(conversation_id),
|
|
||||||
},
|
|
||||||
"isPromptable": is_promptable,
|
"isPromptable": is_promptable,
|
||||||
"first_n_queries": current_n_queries,
|
"first_n_queries": current_n_queries,
|
||||||
"user": user,
|
"user": user,
|
||||||
@@ -154,10 +148,7 @@ class ShareConversation(Resource):
|
|||||||
shared_conversations_collections.insert_one(
|
shared_conversations_collections.insert_one(
|
||||||
{
|
{
|
||||||
"uuid": explicit_binary,
|
"uuid": explicit_binary,
|
||||||
"conversation_id": {
|
"conversation_id": ObjectId(conversation_id),
|
||||||
"$ref": "conversations",
|
|
||||||
"$id": ObjectId(conversation_id),
|
|
||||||
},
|
|
||||||
"isPromptable": is_promptable,
|
"isPromptable": is_promptable,
|
||||||
"first_n_queries": current_n_queries,
|
"first_n_queries": current_n_queries,
|
||||||
"user": user,
|
"user": user,
|
||||||
@@ -175,9 +166,7 @@ class ShareConversation(Resource):
|
|||||||
)
|
)
|
||||||
pre_existing = shared_conversations_collections.find_one(
|
pre_existing = shared_conversations_collections.find_one(
|
||||||
{
|
{
|
||||||
"conversation_id": DBRef(
|
"conversation_id": ObjectId(conversation_id),
|
||||||
"conversations", ObjectId(conversation_id)
|
|
||||||
),
|
|
||||||
"isPromptable": is_promptable,
|
"isPromptable": is_promptable,
|
||||||
"first_n_queries": current_n_queries,
|
"first_n_queries": current_n_queries,
|
||||||
"user": user,
|
"user": user,
|
||||||
@@ -197,10 +186,7 @@ class ShareConversation(Resource):
|
|||||||
shared_conversations_collections.insert_one(
|
shared_conversations_collections.insert_one(
|
||||||
{
|
{
|
||||||
"uuid": explicit_binary,
|
"uuid": explicit_binary,
|
||||||
"conversation_id": {
|
"conversation_id": ObjectId(conversation_id),
|
||||||
"$ref": "conversations",
|
|
||||||
"$id": ObjectId(conversation_id),
|
|
||||||
},
|
|
||||||
"isPromptable": is_promptable,
|
"isPromptable": is_promptable,
|
||||||
"first_n_queries": current_n_queries,
|
"first_n_queries": current_n_queries,
|
||||||
"user": user,
|
"user": user,
|
||||||
@@ -233,10 +219,12 @@ class GetPubliclySharedConversations(Resource):
|
|||||||
if (
|
if (
|
||||||
shared
|
shared
|
||||||
and "conversation_id" in shared
|
and "conversation_id" in shared
|
||||||
and isinstance(shared["conversation_id"], DBRef)
|
|
||||||
):
|
):
|
||||||
conversation_ref = shared["conversation_id"]
|
# conversation_id is now stored as an ObjectId, not a DBRef
|
||||||
conversation = db.dereference(conversation_ref)
|
conversation_id = shared["conversation_id"]
|
||||||
|
conversation = conversations_collection.find_one(
|
||||||
|
{"_id": conversation_id}
|
||||||
|
)
|
||||||
if conversation is None:
|
if conversation is None:
|
||||||
return make_response(
|
return make_response(
|
||||||
jsonify(
|
jsonify(
|
||||||
|
|||||||
114
scripts/migrate_conversation_id_dbref_to_objectid.py
Normal file
114
scripts/migrate_conversation_id_dbref_to_objectid.py
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Migration script to convert conversation_id from DBRef to ObjectId in shared_conversations collection.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import pymongo
|
||||||
|
import logging
|
||||||
|
from tqdm import tqdm
|
||||||
|
from bson.dbref import DBRef
|
||||||
|
from bson.objectid import ObjectId
|
||||||
|
|
||||||
|
# Configure logging
|
||||||
|
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
||||||
|
logger = logging.getLogger()
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
MONGO_URI = "mongodb://localhost:27017/"
|
||||||
|
DB_NAME = "docsgpt"
|
||||||
|
|
||||||
|
def backup_collection(collection, backup_collection_name):
|
||||||
|
"""Backup collection before migration."""
|
||||||
|
logger.info(f"Backing up collection {collection.name} to {backup_collection_name}")
|
||||||
|
collection.aggregate([{"$out": backup_collection_name}])
|
||||||
|
logger.info("Backup completed")
|
||||||
|
|
||||||
|
def migrate_conversation_id_dbref_to_objectid():
|
||||||
|
"""Migrate conversation_id from DBRef to ObjectId."""
|
||||||
|
client = pymongo.MongoClient(MONGO_URI)
|
||||||
|
db = client[DB_NAME]
|
||||||
|
shared_conversations_collection = db["shared_conversations"]
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Backup collection before migration
|
||||||
|
backup_collection(shared_conversations_collection, "shared_conversations_backup")
|
||||||
|
|
||||||
|
# Find all documents and filter for DBRef conversation_id in Python
|
||||||
|
all_documents = list(shared_conversations_collection.find({}))
|
||||||
|
documents_with_dbref = []
|
||||||
|
|
||||||
|
for doc in all_documents:
|
||||||
|
conversation_id_field = doc.get("conversation_id")
|
||||||
|
if isinstance(conversation_id_field, DBRef):
|
||||||
|
documents_with_dbref.append(doc)
|
||||||
|
|
||||||
|
if not documents_with_dbref:
|
||||||
|
logger.info("No documents with DBRef conversation_id found. Migration not needed.")
|
||||||
|
return
|
||||||
|
|
||||||
|
logger.info(f"Found {len(documents_with_dbref)} documents with DBRef conversation_id")
|
||||||
|
|
||||||
|
# Process each document
|
||||||
|
migrated_count = 0
|
||||||
|
error_count = 0
|
||||||
|
|
||||||
|
for doc in tqdm(documents_with_dbref, desc="Migrating conversation_id"):
|
||||||
|
try:
|
||||||
|
conversation_id_field = doc.get("conversation_id")
|
||||||
|
|
||||||
|
# Extract the ObjectId from the DBRef
|
||||||
|
dbref_id = conversation_id_field.id
|
||||||
|
|
||||||
|
if dbref_id and ObjectId.is_valid(dbref_id):
|
||||||
|
# Update the document to use direct ObjectId
|
||||||
|
result = shared_conversations_collection.update_one(
|
||||||
|
{"_id": doc["_id"]},
|
||||||
|
{"$set": {"conversation_id": dbref_id}}
|
||||||
|
)
|
||||||
|
|
||||||
|
if result.modified_count > 0:
|
||||||
|
migrated_count += 1
|
||||||
|
logger.debug(f"Successfully migrated document {doc['_id']}")
|
||||||
|
else:
|
||||||
|
error_count += 1
|
||||||
|
logger.warning(f"Failed to update document {doc['_id']}")
|
||||||
|
else:
|
||||||
|
error_count += 1
|
||||||
|
logger.warning(f"Invalid ObjectId in DBRef for document {doc['_id']}: {dbref_id}")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
error_count += 1
|
||||||
|
logger.error(f"Error migrating document {doc['_id']}: {e}")
|
||||||
|
|
||||||
|
# Final verification
|
||||||
|
all_docs_after = list(shared_conversations_collection.find({}))
|
||||||
|
remaining_dbref = 0
|
||||||
|
for doc in all_docs_after:
|
||||||
|
if isinstance(doc.get("conversation_id"), DBRef):
|
||||||
|
remaining_dbref += 1
|
||||||
|
|
||||||
|
logger.info("Migration completed:")
|
||||||
|
logger.info(f" - Total documents processed: {len(documents_with_dbref)}")
|
||||||
|
logger.info(f" - Successfully migrated: {migrated_count}")
|
||||||
|
logger.info(f" - Errors encountered: {error_count}")
|
||||||
|
logger.info(f" - Remaining DBRef documents: {remaining_dbref}")
|
||||||
|
|
||||||
|
if remaining_dbref == 0:
|
||||||
|
logger.info("✅ Migration successful: All DBRef conversation_id fields have been converted to ObjectId")
|
||||||
|
else:
|
||||||
|
logger.warning(f"⚠️ Migration incomplete: {remaining_dbref} DBRef documents still exist")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Migration failed: {e}")
|
||||||
|
raise
|
||||||
|
finally:
|
||||||
|
client.close()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
logger.info("Starting conversation_id DBRef to ObjectId migration...")
|
||||||
|
migrate_conversation_id_dbref_to_objectid()
|
||||||
|
logger.info("Migration completed successfully!")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Migration failed due to error: {e}")
|
||||||
|
logger.warning("Please verify database state or restore from backups if necessary.")
|
||||||
Reference in New Issue
Block a user