I'm attempting to connect a MonogDB database to my discord.py bot for storage of moderation, user and logging data. I'm new to this kind of thing and I'm having issues closing the connection as it keeps raising "object NoneType can't be used in 'await'expression", even though debugging print statements show it isn't a NoneType.
All referenced functions, classes and class objects/methods are defined, just removed for brevity; can provide further source code if needed.
Relevant source code:
import discord
import motor.motor_asyncio
from discord import app_commands
from pymongo.server_api import ServerApi
class DB_handler():
uri = f'mongodb+srv://ALIXIC_AI:{secret("DB_PASSWORD")}@cluster-1.pw8s6xw.mongodb.net/?retryWrites=true&w=majority&appName=Cluster-1'
@classmethod
async def connect(cls):
motor_client = motor.motor_asyncio.AsyncIOMotorClient(cls.uri, server_api=ServerApi('1'))
try:
await motor_client.admin.command('ping')
conn_message = await style_format("Successfully connected to database\n", "green")
await Utils.console_message("CONN", conn_message, "CONN")
print(motor_client)
return motor_client
except Exception as e:
e = str(e)
conn_message = await style_format(f"Failed to connect to database: {await length_format(e)}\n")
await Utils.console_message("CONN", conn_message, "CONN")
@classmethod
async def close(cls,
motor_client):
if motor_client is not None:
try:
await motor_client.close()
conn_message = await style_format("Safely disconnected from database\n", "green")
await Utils.console_message("CONN", conn_message, "CONN")
except Exception as e:
e = str(e)
conn_message = await style_format(f"Error while closing database connection: {await length_format(e)}", "red")
await Utils.console_message("CONN", conn_message, "CONN")
print()
else:
conn_message = await style_format("No active database connection present.\n", "red")
await Utils.console_message("CONN", conn_message, "CONN")
print()
@client.tree.command(name = "db_test",
description = "DEBUG COMMAND - Developer command to test the database connection")
@app_commands.describe()
async def db_test(interaction: discord.Interaction):
if not await permission_check(Permissions.development, interaction.user.roles): #pyright: ignore
message = f"You are not permitted to run this command {interaction.user.mention}"
await Responses.handler(interaction, message)
else:
message = f"Testing database connection - Triggered by {interaction.user.mention}\nSee console for details"
await Responses.handler(interaction, message)
db_client = await DB_handler.connect()
print(db_client)
print(type(db_client))
await DB_handler.close(db_client)
Console output:
2024-03-25 13:47:34 INFO discord.client logging in using static token
2024-03-25 13:47:35 INFO discord.gateway Shard ID None has connected to Gateway (Session ID: ff5948aeb2fa50ff7e9f8e4e3c2a394a).
2024-03-25 13:47:37 CONN Alixic AI - Alixic#0320 successfully has connected to [AX] Alixic Incorporated
2024-03-25 13:47:37 ACTN Uptime tracking started
2024-03-25 13:47:38 CMD db_test
UID: ################## (@iigibbyz)
CID: 1142244524656173106 (#staff-comms)
2024-03-25 13:47:38 RESP Testing database connection - Triggered by <@##################>
See console for details
2024-03-25 13:47:39 CONN Successfully connected to database
AsyncIOMotorClient(MongoClient(host=['ac-cbuun0h-shard-00-02.pw8s6xw.mongodb.net:27017', 'ac-cbuun0h-shard-00-00.pw8s6xw.mongodb.net:27017', 'ac-cbuun0h-shard-00-01.pw8s6xw.mongodb.net:27017'], document_class=dict, tz_aware=False, connect=False, retrywrites=True, w='majority', appname='Cluster-1', authsource='admin', replicaset='atlas-37pqcs-shard-0', tls=True, server_api=<pymongo.server_api.ServerApi object at 0x7b0519d92170>, driver=DriverInfo(name='Motor', version='3.3.2', platform='asyncio')))
AsyncIOMotorClient(MongoClient(host=['ac-cbuun0h-shard-00-02.pw8s6xw.mongodb.net:27017', 'ac-cbuun0h-shard-00-00.pw8s6xw.mongodb.net:27017', 'ac-cbuun0h-shard-00-01.pw8s6xw.mongodb.net:27017'], document_class=dict, tz_aware=False, connect=False, retrywrites=True, w='majority', appname='Cluster-1', authsource='admin', replicaset='atlas-37pqcs-shard-0', tls=True, server_api=<pymongo.server_api.ServerApi object at 0x7b0519d92170>, driver=DriverInfo(name='Motor', version='3.3.2', platform='asyncio')))
<class 'motor.motor_asyncio.AsyncIOMotorClient'>
2024-03-25 13:47:39 CONN Error while closing database connection: ["object NoneType can't be used in 'await'
expression"]
I modified both the connect and close classmethods to attempt to handle / not provide NoneTypes to no avail. As I'm new, I don't really know where else to go from there.
In your case motor_client is a AsyncIOMotorClient, as mentioned in pymongo documentation
AsyncIOMotorClient.closeis a normal function, not a coroutine. So when doingawait motor_client.close()your code is first executing motor_client.close() which returns None and then awaiting None which raises an error. So removing await in the lineawait motor_client.close()should fix your problem.