tortoise / tortoise/tortoise-orm

GENERATED_SQL in Field does not work as intended (at all)

Open
#1,039 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
I am trying to create a field that has auto increment but is not a pk. I am trying to create an Object like IntField with the adjusted GENERATED_SQL variable but I don't get the expected behaviour.

To Reproduce

class MyField(Field, int):
    """
    Integer field.
    """
    SQL_TYPE = "INT"
    allows_generated = True

    def __init__(self, **kwargs: Any) -> None:
        kwargs["generated"] = bool(kwargs.get("generated", True))
        super().__init__(**kwargs)

    @property
    def constraints(self) -> dict:
        return {
            "ge": 1,
            "le": 9,
        }

    class _db_postgres:
        GENERATED_SQL = "SERIAL NOT NULL"

    class _db_sqlite:
        GENERATED_SQL = "INTEGER AUTOINCREMENT NOT NULL"

    class _db_mysql:
        GENERATED_SQL = "INT NOT NULL AUTO_INCREMENT"

In a model then I define

newfield = MyField(generated=True)

Using aerich to generate a migration I get:

...
"newfield" INT NOT NULL,
...

Expected behavior

...
"newfield" SERIAL NOT NULL,
...

Additional context
Changing SQL_TYPE solves the problem (e.g. to SERIAL) but was not my first idea since there is a generate keyword.
It seems that the GENERATED_SQL only kicks in if it is a primary key.

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

Reproduce the custom MyField example and generate a migration with aerich, then trace how Field.GENERATED_SQL is selected for non-primary-key fields across PostgreSQL, SQLite, and MySQL. Done means the generated migration uses the backend-specific GENERATED_SQL value, such as SERIAL NOT NULL for PostgreSQL, while preserving existing primary-key behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
mysql, postgresql, python, sqlite
Domain
database
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
32/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.