Gino: NoneType object has no attribute all

Created on 10 Jul 2018  路  8Comments  路  Source: python-gino/gino

  • GINO version: 0.7.4
  • Python version: 3.5.5
  • asyncpg version: 0.16.0
  • aiocontextvars version: 0.1.2
  • PostgreSQL version: 9.3.15

Description

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'

What I Did

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.

question wontfix

Most helpful comment

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())

All 8 comments

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

  1. Are you sure on_ready() is called before on_member_update() please?
  2. Please try accessing the database in DatabaseInterface.connect().
  3. Please check 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!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Pehat picture Pehat  路  3Comments

AmatanHead picture AmatanHead  路  5Comments

marcojulioarg picture marcojulioarg  路  3Comments

filantus picture filantus  路  3Comments

ape364 picture ape364  路  6Comments