# Using GeneratedField with Postgres

**URL:** <https://forum.djangoproject.com/t/using-generatedfield-with-postgres/27224>\
**Category:** ORM\
**Created:** [January 20, 2024, 5:34pm UTC](https://forum.djangoproject.com/t/using-generatedfield-with-postgres/27224 "2024-01-20T17:34:36Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![mdlattimore](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/mdlattimore/32/17623_2.png) [@mdlattimore](https://forum.djangoproject.com/u/mdlattimore)\
**Post date:** [January 20, 2024, 5:34pm UTC](https://forum.djangoproject.com/t/using-generatedfield-with-postgres/27224/1 "2024-01-20T17:34:37Z")

</div>

I have an app using the new (in Django 5) GeneratedField field. Here’s the model:

```auto
class Artist(models.Model):
    first_name = models.CharField(max_length=50, verbose_name="First Name")
    middle_name = models.CharField(max_length=50, verbose_name="Middle Name", null=True, blank=True)
    last_name = models.CharField(max_length=50, verbose_name="Last Name")
    full_name = models.GeneratedField(
        expression=Concat("first_name", models.Value(" "), "middle_name", models.Value(" "),"last_name"),
        output_field=models.CharField(max_length=100),
        db_persist = True,
        verbose_name="Full Name"
    )
    birth_year = models.IntegerField(verbose_name="Year of Birth")
    nationality = models.CharField(max_length=100, verbose_name="Nationality")

    def __str__ (self):
        return f"{self.full_name}"

```

When attempting to deploy to [Fly.io](http://Fly.io), the deployment fails with the error:

`django.db.utils.ProgrammingError: generation expression is not immutable`

which causes the the release command to fail. It looks like the GeneratedField is the culprit. If I remove the GeneratedField, the app deploys without error. According the the Model Field Reference, " PostgreSQL requires functions and operators referenced in a generated column to be marked as `IMMUTABLE` ." Is there a way to successfully use a GeneratedField with Postgres?

---

<div class="post-metadata">

**Author:** ![felixxm](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/felixxm/32/2479_2.png) [@felixxm](https://forum.djangoproject.com/u/felixxm)\
**Post date:** [January 20, 2024, 6:06pm UTC](https://forum.djangoproject.com/t/using-generatedfield-with-postgres/27224/2 "2024-01-20T18:06:26Z")

</div>

PostgreSQL requires functions and operators referenced in a generated column to be marked as `IMMUTABLE`. Unfortunately, PostgreSQL’s `CONCAT` is not considered an immutable, that’s why in Django 5.1 we’ve changed the implementation of Django’s `Concat()` to use `||`

> <https://github.com/django/django/commit/6364b6ee1071381eb3a23ba6b821fc0d6f0fce75>
>
> This also avoids casting string based expressions in Concat() on
> PostgreSQL.

---

<div class="post-metadata">

**Author:** ![mdlattimore](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/mdlattimore/32/17623_2.png) [@mdlattimore](https://forum.djangoproject.com/u/mdlattimore)\
**Post date:** [January 20, 2024, 6:51pm UTC](https://forum.djangoproject.com/t/using-generatedfield-with-postgres/27224/3 "2024-01-20T18:51:24Z")

</div>

Thanks for the info – certainly answers my question. Are you aware of a workaround pending the release of 5.1? I’m one of those “non-expert users” to whom Paolo refers.

---

<div class="post-metadata">

**Author:** ![felixxm](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/felixxm/32/2479_2.png) [@felixxm](https://forum.djangoproject.com/u/felixxm)\
**Post date:** [January 20, 2024, 6:55pm UTC](https://forum.djangoproject.com/t/using-generatedfield-with-postgres/27224/4 "2024-01-20T18:55:10Z")

</div>

You can copy the new implementation of `Concat()` and `ConcatPair()` into your code, and use it instead of builtin version:

> <https://github.com/django/django/blob/4879907223d70ee1a82474d9286ccfa5dae96971/django/db/models/functions/text.py#L68-L148>

---

<div class="post-metadata">

**Author:** ![pauloxnet](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/pauloxnet/32/11021_2.png) [@pauloxnet](https://forum.djangoproject.com/u/pauloxnet)\
**Post date:** [January 20, 2024, 7:07pm UTC](https://forum.djangoproject.com/t/using-generatedfield-with-postgres/27224/5 "2024-01-20T19:07:29Z")

</div>

I wrote some articles about GeneratedField, and one specific for PostgreSQL with a text concatenation example  
[https://www.paulox.net/2023/11/24/database-generated-columns-part-2-django-and-postgresql/#a-calculated-concatenated-field](https://www.paulox.net/2023/11/24/database-generated-columns-part-2-django-and-postgresql/#a-calculated-concatenated-field)

Let me know if it’s clear for you and if it solves your problem.

---

<div class="post-metadata">

**Author:** ![mdlattimore](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/mdlattimore/32/17623_2.png) [@mdlattimore](https://forum.djangoproject.com/u/mdlattimore)\
**Post date:** [January 20, 2024, 9:14pm UTC](https://forum.djangoproject.com/t/using-generatedfield-with-postgres/27224/6 "2024-01-20T21:14:58Z")

</div>

Gentlemen, thank you so much for your help. I’ve tried both solutions. The good news is both do solve the deployment problem – the app deploys without error. However, when saving a model instance that uses a GeneratedField (using the Django Admin), I get a new error:

```auto
IntegrityError at /admin/art/artist/add/
null value in column "full_name" of relation "art_artist" violates not-null constraint
DETAIL: Failing row contains (10, Pablo, null, Picasso, null, 1889, Spanish).
Request Method:	POST
Request URL:	http://curated-arts.fly.dev/admin/art/artist/add/
Django Version:	5.0.1
Exception Type:	IntegrityError
Exception Value:	
null value in column "full_name" of relation "art_artist" violates not-null constraint
DETAIL: Failing row contains (10, Pablo, null, Picasso, null, 1889, Spanish).
Exception Location:	/usr/local/lib/python3.12/site-packages/psycopg/cursor.py, line 732, in execute
Raised during:	django.contrib.admin.options.add_view
Python Executable:	/usr/local/bin/python
Python Version:	3.12.1
Python Path:	
['/code',
 '/usr/local/bin',
 '/usr/local/lib/python312.zip',
 '/usr/local/lib/python3.12',
 '/usr/local/lib/python3.12/lib-dynload',
 '/usr/local/lib/python3.12/site-packages']
Server time:	Sat, 20 Jan 2024 20:56:41 +0000

```

I assume the not null constraint is a default setting for GeneratedField? Is there a way to remove the not null constraint?
