I am trying to get all the rows that matches a few filter conditions. Then I would like it to be ordered by a column. However, it produces an error saying that it doesn't have an attribute all. I am trying to follow the documentation (3rd codeblock) and implement gino for my specific needs.
Here is the traceback.
Traceback (most recent call last):
File "/usr/local/lib/python3.5/dist-packages/discord/client.py", line 220, in _run_event
await coro(*args, **kwargs)
File "/home/ubuntu/workspace/discordbot/titanembeds/bot.py", line 179, in on_member_update
await self.database.update_guild_member(memberafter)
File "/home/ubuntu/workspace/discordbot/titanembeds/database/__init__.py", line 120, in update_guild_member
.order_by(GuildMembers.id).gino.all()
File "/usr/local/lib/python3.5/dist-packages/gino/api.py", line 124, in all
return await self._query.bind.all(self._query, *multiparams, **params)
AttributeError: 'NoneType' object has no attribute 'all'
dbmember = await GuildMembers.query \
.where(GuildMembers.guild_id == int(member.guild.id)) \
.where(GuildMembers.user_id == int(member.id)) \
.order_by(GuildMembers.id).gino.all()
I am querying the GuildMembers object/table that matches the given guild_id and user_id columns. Then I would like it to order by the row ID (primary key).
Any help is appreciated.
From the error message, bind is None. I suspect the engine is not set up properly or the context has no knowledge of the engine.
I currently have a class dedicated to handling the database.
It looks something like
from gino import Gino
db = Gino()
from package.database.guild_members import GuildMembers
class DatabaseInterface(object):
def __init__(self, bot):
self.bot = bot
async def connect(self, dburi):
await db.set_bind(dburi)
async def handle_guild_members(self, member):
dbmember = await GuildMembers.query \
.where(GuildMembers.guild_id == int(member.guild.id)) \
.where(GuildMembers.user_id == int(member.id)) \
.order_by(GuildMembers.id).gino.all()
guild_members.py looks something like
from package.database import db
class GuildMembers(db.Model):
__tablename__ = "guild_members"
id = db.Column(db.Integer, primary_key=True) # Auto incremented id
# //
And my main application looks something like
from package.database import DatabaseInterface
import config
class MyApp:
def __init__(self):
self.database = DatabaseInterface(self)
def run(self):
self.loop.run_until_complete(self.start())
async def start(self):
await self.database.connect(config["database-uri"])
await self.database.handle_guild_members(Object)
te = MyApp()
te.run()
Is it because bind_url is not in the same function as handle_guild_members?
I don't see a problem with your example. bind_url doesn't need to be in the same function.
The following runs successfully on mine. It's better to debug if you can have a runnable example that can reproduce the issue.
import asyncio
from gino import Gino
db = Gino()
class Database:
async def connect(self):
await db.set_bind('postgres://localhost/gino')
async def query(self):
print(await User.query.gino.all())
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.BigInteger(), primary_key=True)
async def main():
database = Database()
await database.connect()
await database.query()
asyncio.get_event_loop().run_until_complete(main())
In that case, I have pushed what I have in my development. https://github.com/TitanEmbeds/Titan/blob/gino/discordbot/titanembeds/database/__init__.py#L120
Are you alright with looking through my codebase and pinpoint the issue?
Sure, but I'll get back to you later today
@EndenDragon
on_ready() is called before on_member_update() please?DatabaseInterface.connect().db.bind in update_guild().I refractored my code so that set_bind happens before the bot is even initialized. Works like a charm, thanks!!
https://github.com/TitanEmbeds/Titan/pull/112/commits/de94f87c456ec4a713e24911243a881e72c9f030#diff-e9efb373550a65452e49304c8856fe5c
Glad it works for you!
Most helpful comment
I don't see a problem with your example.
bind_urldoesn't need to be in the same function.The following runs successfully on mine. It's better to debug if you can have a runnable example that can reproduce the issue.