Ticket: Migration, Having a problem with pymongo

Hi,
Having a problem with pymongo
bson.errors.InvalidDocument: Cannot encode object: {‘lastupdated’, datetime.datetime(2015, 8, 26, 0, 3, 50)}

How did you people solve this? any ideas?

Welcome to the community @Haki_Dere,

This looks related to the Ticket: Migration exercise and the updates for movie_last_updated_migration.py, can you confirm if my understanding is correct?

If this is correct, have you edited this file and specifically updated this line:

predicate = {"some_field": {"$some_operator": "some_expression"}}

In terms of the update necessary to the code, it will involve the field “lastupdated” and two operators ("$exists" and “$type”).

Can you share the code you have updated for those two lines as both of these need to be updated in the file movie_last_updated_migration.py for that specific exercise?

Hope this helps and please let me know if I’ve mistaken your question and it relates to a different lesson/exercise.

Kindest regards,
Eoin

1 Like

Hey Eoin,
Thanks for your response, very kind of you!.
Here is the code:

pymongo version: pymongo==3.7.2

predicate = {"lastupdated": {"$type": "string"}}
projection = {"lastupdated": 1}

cursor = mflix.movies.find(predicate, projection)

# this will transform the "lastupdated" field to an ISODate() from a string
movies_to_migrate = []
for doc in cursor:
    doc_id = doc.get('_id')
    lastupdated = doc.get('lastupdated', None)
    movies_to_migrate.append(
        {
            "doc_id": ObjectId(doc_id),
            "lastupdated": parser.parse(lastupdated)
        }
    )

print(f"{len(movies_to_migrate)} documents to migrate")

try:

    # build the UpdateOne so it updates the "lastupdated" field to contain
    # the new ISODate() type
    bulk_updates = [UpdateOne(
        {"_id": movie.get("doc_id")},
        {"$set": {"lastupdated", movie.get("lastupdated")}}
    ) for movie in movies_to_migrate]

    # here's where the bulk operation is sent to MongoDB
    bulk_results = mflix.movies.bulk_write(bulk_updates)
    print(f"{bulk_results.modified_count} documents updated")

except InvalidOperation:
    print("no updates necessary")
except Exception as e:
    raise e

Hi @Haki_Dere

You should also add “$exists”: True to your predicate, the rest of your code looks correct.

Kindest regards,
Eoin

I had the same issue and the error in my opinion is related to the comma separator used instead of colon in the $set expression:
{"$set": {"lastupdated", movie.get("lastupdated")}}
instead of:
{"$set": {"lastupdated": movie.get("lastupdated")}}

Hi @Riccardo_Canta - welcome to forums!

You are correct, the ‘,’ comma character is used as a separator for name/value pairs within a document per the JSON specification (https://www.json.org/json-en.html).

The ‘:’ semicolon character is used to follow each name and precedes each pair in the name value pair, so it should always be “field” then “:” then “pair” or “lastupdated”: movie.get(“lastupdated”) as you highlight above.

Let me know if this helps resolve your issue and good luck with the rest of the course.

Kindest regards,
Eoin

Thanks for the information. It is really helpful content for us. Looking for the same answer.

Hi @Dorothea_Heidenreich- welcome to the forums,

Did this help solve your issue? If not, can you outline what problem(s) you are having now.

Kindest regards,
Eoin