Search code examples
pythonsqlalchemytype-hintingmypy

Type annotations for sqlalchemy model declaration


I can't figure how i could type annotate my sqlalchemy models code, what kind of type should i use for my model fields.

class Email(Model):
    __tablename__ = 'emails'

    name: Column[str] = Column(String, nullable=False)
    sender: Column[str] = Column(
        String, default=default_sender, nullable=False
    )
    subject: Column[str] = Column(String, nullable=False)
    html: Column[str] = Column(String, nullable=False)
    template_id: Column[UUID] = Column(
        postgresql.UUID(as_uuid=True),
        ForeignKey('templates.id'),
        index=True,
    )

Column type as well as Mapped satisfies the type linter of my editor, but it doesn't look like the right one as opposed to simple types like str/int/uuid

Should i use Optional[Column[str]] or Column[Optional[str]]?

What to use for relationship?

class Foo(Model):
    ...
    bar: Bar = relationship(
        'Bar',
        order_by="desc(Bar.created_at)",
        lazy='dynamic',
    )

The result of accessing the relationship varies depending on the attribute lazy.


Solution

  • For SQLAlchemy 2.0 it would be something like:

    import uuid
    from sqlalchemy.orm import Mapped, mapped_column
    from sqlalchemy.dialects.postgresql import UUID
    
    class Email(Model):
        __tablename__ = 'emails'
    
        name: Mapped[str] = mapped_column(String, nullable=False)
        sender: Mapped[str] = mapped_column(
            String, default=default_sender, nullable=False
        )
        subject: Mapped[str] = mapped_column(String, nullable=False)
        html: Mapped[str] = mapped_column(String, nullable=False)
        template_id: Mapped[uuid.UUID] = mapped_column(
            UUID(as_uuid=True),
            ForeignKey('templates.id'),
            index=True,
        )