tortoise / tortoise/tortoise-orm

AttributeError: 'NoneType' object has no attribute 'total_changes'

Open
#706 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
5.6k
Forks
516
Avg merge
2d 21h
Merged PRs (30d)
9

Description

Traceback (most recent call last):
  File "/usr/local/lib/python3.7/dist-packages/discord/client.py", line 343, in _run_event
    await coro(*args, **kwargs)
  File "/home/tf2maps/bot_zeus/cogs/tags.py", line 27, in on_message
    tag = await Tag.filter(key=key)
  File "/usr/local/lib/python3.7/dist-packages/tortoise/queryset.py", line 842, in _execute
    ).execute_select(self.query, custom_fields=list(self._annotations.keys()))
  File "/usr/local/lib/python3.7/dist-packages/tortoise/backends/base/executor.py", line 124, in execute_select
    _, raw_results = await self.db.execute_query(query.get_sql())
  File "/usr/local/lib/python3.7/dist-packages/tortoise/backends/sqlite/client.py", line 29, in translate_exceptions_
    return await func(self, query, *args)
  File "/usr/local/lib/python3.7/dist-packages/tortoise/backends/sqlite/client.py", line 133, in execute_query
    start = connection.total_changes
AttributeError: 'NoneType' object has no attribute 'total_changes'

Summary
I believe that there is an issue with the Tortoise.init finding and creating the database connection

There is code calling the init function from main.py, and the model in question is used later in a plugin under cogs/tags.py

The code below is just snippets for the sake of brevity.
If there is some way I can confirm that the connection is not active by getting a property on the Tag object
Or it would be nice if I could explictly tell the init function to initalize models that i have directly imported instead of passing a string to it.

Folder structure:

├── main.py
├── tags.sqlite
├── cogs/
│   ├── __init__.py
│   ├── tags.py
├── models/
│   ├── __init__.py
│   └── Tag.py

Main.py

...
await Tortoise.init(
    db_url="sqlite://tags.sqlite",
    modules={'models': ["models.Tag"]}
)
...

cogs/tags.py

...
async def on_message(self, message):
    key = message.content.lower()
    tag = await Tag.filter(key=key)
    await message.channel.send(tag.value)
...

models/Tag.py

from tortoise import Tortoise, fields
from tortoise.models import Model

class Tag(Model):
    id = fields.IntField(pk=True)
    key = fields.TextField()
    value = fields.CharField(max_length=1024)
    author = fields.CharField(max_length=128)
    date = fields.DatetimeField(null=True)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the Tortoise.init call in main.py and the Tag.filter use in cogs/tags.py, then trace the SQLite connection handling in tortoise/backends/sqlite/client.py where total_changes is accessed. Reproduce the example and confirm the initialization order and connection state; done means Tag.filter no longer reaches this AttributeError and the expected initialization behavior is clear.

Written by the indexing model from the issue text.

Assessment

Tech stack
python, sqlite
Domain
backend, databases
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.