tortoise / tortoise/tortoise-orm
AttributeError: 'NoneType' object has no attribute 'id', trying to remove a foreign key from a row or set it to null.
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 5.6k
- Forks
- 516
- Avg merge
- 2d 21h
- Merged PRs (30d)
- 9
Description
Describe the bug
A clear and concise description of what the bug is.
I need to be able to remove/null a foreign key. It is set to NOT NULL in the model. But seem to be having issues.
Ignoring exception in command: 'NoneType' object has no attribute 'id':
Traceback (most recent call last):
File "/project/bombot/venv/lib/python3.10/site-packages/twitchio/ext/commands/core.py", line 217, in invoke
await self._callback(*args, *context.args, **context.kwargs)
File "/project/bombot/app/modules/cogs/bom_mod_commands.py", line 40, in remove
await Player.get(name=playername).update(clan=None, enabled=False)
File "/project/bombot/venv/lib/python3.10/site-packages/tortoise/queryset.py", line 1105, in __await__
self._make_query()
File "/project/bombot/venv/lib/python3.10/site-packages/tortoise/queryset.py", line 1082, in _make_query
getattr(value, field_object.to_field_instance.model_field_name), None
AttributeError: 'NoneType' object has no attribute 'id'
To Reproduce
Steps to reproduce the behavior, preferably a small code snippet.
models.py:
class Clan(Model):
id = fields.IntField(pk=True)
name = fields.CharField(max_length=255, unique=True)
tag = fields.CharField(max_length=4, unique=True)
class StatusManager(Manager):
def get_queryset(self):
return super(StatusManager, self).get_queryset().filter(enabled=True)
class Player(Model):
id = fields.IntField(pk=True)
name = fields.CharField(max_length=255, unique=True)
clan = fields.ForeignKeyField('models.Clan', related_name='players', null=True)
enabled = fields.BooleanField(default=True)
enabled_players = StatusManager()
def is_enabled(self) -> bool:
return self.enabled
commands.py:
@commands.command()
async def remove(self, ctx: commands.Context, playername: str) -> None:
"""
!remove command
"""
if (await Player.get(name=playername).exists()):
if ((await Player.get(name=playername)).is_enabled()):
await Player.get(name=playername).update(clan=None, enabled=False)
await ctx.send(f"Removed @{playername} from their clan!")
else:
await ctx.send(f"@{playername} is not in a Clan roster!")
else:
await ctx.send(f"@{playername} does not currently exist!")
Expected behavior
A clear and concise description of what you expected to happen.
The field should be NULLED.
Additional context
Add any other context about the problem here.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in tortoise/queryset.py around _make_query, where the traceback reaches line 1082 while updating Player.clan. Reproduce the shown nullable ForeignKeyField update with clan=None, then verify that the foreign-key column is set to NULL without the AttributeError.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- database
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100