Skip to main content

prefer-identity

problem

Serial types make permissions and schema management difficult. Identity columns are standard SQL and have more features and better usability.

solution

Instead of:

create table app.users
(
id bigserial
)

Use:

create table app.users
(
id bigint generated by default as identity primary key
)

solution for alembic and sqlalchemy

As of sqlalchemy 1.4, use:

# models.py
import sqlalchemy as sa

class User(BaseModel):
id = sa.Column(sa.Integer, sa.Identity(), primary_key=True)

For sqlalchemy 1.3 or prior built-in support for rendering of IDENTITY is not available yet, however the following compilation hook may be used to replace occurrences of SERIAL with IDENTITY. See the SQLAlchemy docs for more information.

from sqlalchemy.schema import CreateColumn
from sqlalchemy.ext.compiler import compiles

@compiles(CreateColumn, "postgresql")
def use_identity(element, compiler, **kw):
text = compiler.visit_create_column(element, **kw)
text = text.replace("SERIAL", "INT GENERATED BY DEFAULT AS IDENTITY")
return text