Home > Mobile >  how handle this error in pymongo duplicate error?
how handle this error in pymongo duplicate error?

Time:06-26

I created a telegram bot that saves everyone who launched the bot to the pymongo database. I have this problem: if the user clicks again on the start, there will be an error: pymongo.errors.DuplicateKeyError: [...] How to process it?

import motor.motor_asyncio
from datetime import datetime
from aiogram import Bot, types
from aiogram.dispatcher import Dispatcher
from aiogram.utils import executor

TOKEN = ''
cluster = motor.motor_asyncio.AsyncIOMotorClient('')
collection = cluster.Dimalexus.BOT

bot = Bot(token=TOKEN)
dp = Dispatcher(bot)

def add_user(user_id, user_name, name):
    date = datetime.now().date()
    collection.insert_one({
        '_id' : user_id,
        'name' : name,
        "username" : user_name,
        "date" : str(date)
        })

@dp.message_handler(commands=['start'])
async def welcome_send_info(message: types.Message):
    await message.reply('привет')
    name = message.from_user.full_name
    user_name = message.from_user.username
    user_id = message.from_user.id
    try:
        add_user(user_id, user_name, name)
    except Exception as e:
        print(e)

if __name__ == "__main__":
    executor.start_polling(dp, skip_updates=True)

Try-except not working

CodePudding user response:

that is a Duplicate Error that occurs because you're trying to insert a value that already exists in that document.

To handle this, you can try using another function instead of insert_one(): update_one(). This one is usually used to update a record that already exists, but you can use the parameter upsert = True to insert a new one if no documents with that filter are found.

As said here the function mainly accepts two arguments and others that are optional:

  1. filter: this one is used to find the record to update;
  2. new_values: the value updated;
  3. upsert: this is the parameter that you need.

The code that you will need will be:

def add_user(user_id, user_name, name):
    date = datetime.now().date()
    collection.update_one({
        "_id" : user_id
        }, {
        '_id' : user_id,
        'name' : name,
        "username" : user_name,
        "date" : str(date)
        }, upsert = True)

With this, you will be searching for that ID. If not found it creates a new record, otherwise you'll be alright with the record already set up :)

CodePudding user response:

_id is a unique id, you can't add multiples time. Use update with upsert:

collection.update_one(
    {
       "_id" : user_id
    }, 
    {
       '_id' : user_id,
       'name' : name,
       "username" : user_name,
       "date" : str(date)
    }, upsert=True)

Or you can search for the _id in the database, if already exists, you don't add.

  • Related