Opened 2 hours ago

Last modified 96 minutes ago

#37208 new Bug

db_persist has problem with postgres

Reported by: Twili Spar Owned by:
Component: Database layer (models, ORM) Version: 6.0
Severity: Normal Keywords: db_persist, GeneratedField
Cc: Twili Spar Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Environment:

Python version: 3.13.3
Django version: 6.0.7
psycopg version: 3.2.12
Postgres version: 18.1


Explain the bug:

Here is my code:

tmp = models.GeneratedField(
        db_persist=False,  # In here, I've set the column type as virtual
        expression=models.Q(standard_symbol_tmp__isnull=False),
        null=True,
        output_field=models.BooleanField(),
    )

And when I do makemigrations all things are good, but on migrating, django says:

SystemCheckError: System check identified some issues:

ERRORS:
symbol.Symbol.tmp: (fields.E221) PostgreSQL does not support non-persisted GeneratedFields.
        HINT: Set db_persist=True on the field.

While I know that Postgres supports the VIRTUAL and STORED generated columns, here is the postgres release note ref:
https://www.postgresql.org/about/news/postgresql-18-released-3142/

While the migration file is created and is like:

class Migration(migrations.Migration):

    # ...rest of the code ...

    operations = [
        migrations.AddField(
            model_name="symbol",
            name="tmp",
            field=models.GeneratedField(
                db_persist=False,
                expression=models.Q(("standard_symbol_tmp__isnull", False)),
                null=True,
                output_field=models.BooleanField(),
            ),
        ),
    ]

And when I set db_persist to True AND DO NOT TOUCH THE migration file and migrate, all things are good, column creates as VIRTUAL in postgres, NOT STORED.

Change History (1)

comment:1 by Twili Spar, 112 minutes ago

A quick fix

I didn't changed the migration file, keep that as like:

operations = [
        migrations.AddField(
            model_name="symbol",
            name="tmp",
            field=models.GeneratedField(
                db_persist=False,  # 👈 NOTE, this hasn't changed
                expression=models.Q(("standard_symbol_tmp__isnull", False)),
                null=True,
                output_field=models.BooleanField(),
            ),
        ),
    ]

And changed the model and set db_persist=True, then DID NOT create new migration file, then all things worked.
I know I could also do a fake migration too.

Version 0, edited 112 minutes ago by Twili Spar (next)
Note: See TracTickets for help on using tickets.
Back to Top