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:
filter
: this one is used to find the record to update;new_values
: the value updated;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.