pythonmongodbpymongo

Unique Object_id from timestamp with Python


I am creating a collection in MongoDB using pymongo. The elements of the collection already have a creation_date and I would like to use that to create the _id field. Since there is the possibility that more elements share the same creation_date, how can I create unique Object_id from that field?

bson has a function: bson.ObjectId.from_datetime(timestamp) which warns about the non uniqueness of the generated id. Is there a way to add some randomness to it such that different object_ids are generated from the same date?


Solution

  • The bson.ObjectId return a 24 hex digits variable which the first 8 digits is depends on the time and the remaining digits are some random number. If you create an id by using bson.ObjectId.from_datetime(args) function, it returns a 24 hex digits variable which last 16 digits are zero. By adding a random number to last part you can make it unique.

    For generating random number you can use bson.ObjectId itself (last 16 digits).

    ps: bson.ObjectId() returns a class instance and you should convert it into string.

    import time
    from datetime import datetime
    import bson
    
    def uniqueTimeIdCreator(_time = time.time()):
    
        date = datetime.fromtimestamp(_time)
        timeId = str(bson.ObjectId.from_datetime(date))
        uniqueId = str(bson.ObjectId())
    
        return timeId[0:8] + uniqueId[8:]
    
    specTime = time.time()
    
    id1 = uniqueTimeIdCreator(specTime)
    id2 = uniqueTimeIdCreator(specTime)
    
    print(id1)
    print(id2)
    

    You can check that id1 and id2 are the same timestamp constructing datetimes back from the strings:

    t1 = bson.ObjectId(id1).generation_time
    t2 = bson.ObjectId(id2).generation_time
    
    print(t1)
    print(t2)