Describe the bug
When a CREATE TABLE DDL uses the Postgres shorthand type TIMESTAMPTZ (equivalent to TIMESTAMP WITH TIME ZONE), omm -m sqlalchemy does not classify it as a known type. Instead it emits the literal token timestamptz as a bare Python identifier in the generated models file, e.g.:
created_at = sa.Column(timestamptz(), nullable=False, server_default='NOW()')
The resulting file fails to import — Python raises NameError: name 'timestamptz' is not defined and IDEs flag Unresolved reference 'timestamptz'. The same issue occurs with TIMETZ (shorthand for TIME WITH TIME ZONE).
The canonical SQL spelling TIMESTAMP WITH TIME ZONE is parsed correctly and produces DateTime(timezone=True), so the underlying type is supported — only the Postgres shorthand alias is missing.
To Reproduce
Steps to reproduce the behavior:
- Save the following minimal DDL as repro.sql:
CREATE TABLE users (
id UUID PRIMARY KEY,
email VARCHAR(320) NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
- Run
omm repro.sql -m sqlalchemy -t models.py
- Open
models.py and observe sa.Column(timestamptz, ...) for created_at / updated_at — note the bare identifier with no import.
- Run
python -c "import models" and see NameError: name 'timestamptz' is not defined.
Expected behavior
TIMESTAMPTZ (and TIMETZ) should be recognised as Postgres aliases for TIMESTAMP WITH TIME ZONE / TIME WITH TIME ZONE and emitted as sa.DateTime(timezone=True) / sa.Time(timezone=True), with the corresponding symbol included in from sqlalchemy import …. This matches the behaviour of sqlacodegen and the actual semantics used by Postgres and SQLAlchemy.
Screenshots
N/A — text-only output. Sample of the broken generated file:
import sqlalchemy as sa
from sqlalchemy.ext.declarative import declarative_base
from enum import Enum
from sqlalchemy.dialects.postgresql import JSONB,UUID
Base = declarative_base()
class Users(Base):
__tablename__ = 'users'
id = sa.Column(UUID, server_default='gen_random_uuid()', primary_key=True)
email = sa.Column(sa.String(320), nullable=False, unique=True)
name = sa.Column(sa.String(200))
role = sa.Column(sa.Enum(UserRole), nullable=False)
status = sa.Column(sa.Enum(UserStatus), nullable=False, server_default='INVITED')
created_at = sa.Column(timestamptz(), nullable=False, server_default='NOW()')
updated_at = sa.Column(timestamptz(), nullable=False, server_default='NOW()')
Desktop (please complete the following information):
- OS: MacOS Tahoe
- Browser: N/A
- Version: 26.2
Smartphone (please complete the following information):
- N/A — CLI tool, not run on mobile.
Additional context
Describe the bug
When a CREATE TABLE DDL uses the Postgres shorthand type TIMESTAMPTZ (equivalent to TIMESTAMP WITH TIME ZONE), omm -m sqlalchemy does not classify it as a known type. Instead it emits the literal token timestamptz as a bare Python identifier in the generated models file, e.g.:
The resulting file fails to import — Python raises NameError: name 'timestamptz' is not defined and IDEs flag Unresolved reference 'timestamptz'. The same issue occurs with TIMETZ (shorthand for TIME WITH TIME ZONE).
The canonical SQL spelling TIMESTAMP WITH TIME ZONE is parsed correctly and produces DateTime(timezone=True), so the underlying type is supported — only the Postgres shorthand alias is missing.
To Reproduce
Steps to reproduce the behavior:
omm repro.sql -m sqlalchemy -t models.pymodels.pyand observesa.Column(timestamptz, ...)forcreated_at/updated_at— note the bare identifier with no import.python -c "import models"and seeNameError: name 'timestamptz' is not defined.Expected behavior
TIMESTAMPTZ (and TIMETZ) should be recognised as Postgres aliases for TIMESTAMP WITH TIME ZONE / TIME WITH TIME ZONE and emitted as sa.DateTime(timezone=True) / sa.Time(timezone=True), with the corresponding symbol included in from sqlalchemy import …. This matches the behaviour of sqlacodegen and the actual semantics used by Postgres and SQLAlchemy.
Screenshots
N/A — text-only output. Sample of the broken generated file:
Desktop (please complete the following information):
Smartphone (please complete the following information):
Additional context