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.
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.