@charettes thank you - that was the breadcrumb I needed. The following rough implementation works:
class Default(Expression):
def as_sql(self, compiler, connection):
return "DEFAULT", []
class AutoPositiveBigIntegerField(models.PositiveBigIntegerField):
@property
def db_returning(self):
return True
def get_default(self):
return Default()
class Invoice(models.Model):
...
number = AutoPositiveBigIntegerField(unique=True)
The above, coupled with the following manual migration on the number
field:
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("billing", "0003_my_migration"),
]
operations = [
migrations.RunSQL(
"ALTER TABLE invoice ALTER COLUMN number ADD GENERATED BY DEFAULT AS IDENTITY;",
reverse_sql="ALTER TABLE invoice ALTER COLUMN number DROP IDENTITY IF EXISTS;"
),
]