tortoise / tortoise/tortoise-orm

Error message on `get_or_create`

Open
#744 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

Describe the bug
When performing a get_or_create with arguments missing to creating a model (and the model does not exist in the DB), it should raise an IntegretyError, but instead, it raises a DoesNotExist.

To Reproduce
Notice that the get_or_create is missing the required parameter name.

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

class Event(Model):
    id = fields.IntField(pk=True)
    name = fields.TextField()
    color = fields.TextField()

async def run():
    await Tortoise.init(
        db_url="mysql://root:secret@localhost:3306/test", modules={"models": ["__main__"]}
    )
    await Tortoise.generate_schemas()
    await Event.get_or_create(color="red")

if __name__ == "__main__":
    run_async(run())

raises:

DoesNotExist: Object does not exist

Expected behavior
Up until commit 8bf3c4aac66e4579d61d06de3df363295eb36fc2 it was raising the expected error.
I'm sure that this behavior was fixed in some commit after 0.17.0 (because it was returning DoesNotExist back then too.)

IntegrityError: (1048, "Column 'name' cannot be null")

Additional context
I know it kind of dubious, should we raise a DoesNotExist (tried to get but couldn't get) or IntegretyError (tried to create but failed to create).

I'm in favor of the latter, an user of get_or_create is typically using this method to create an object if it does not exists and expecting an object with all the arguments passed.
Otherwise, it would just use get and therefore we should stick to the create issues.

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

Locate the Python implementation of get_or_create and reproduce the reported case with the Event model, a missing name, and color="red" against MySQL. Check the behavior before and after the referenced commit; done means the missing required field raises IntegrityError rather than DoesNotExist, with coverage for the regression.

Written by the indexing model from the issue text.

Assessment

Tech stack
mysql, python
Domain
database
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.