FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

🏷️ Adjust type annotation for `Field.sa_type` to support instantiated SQLAlchemy types by diachkow · Pull Request #1345 · fastapi/sqlmodel · GitHub

Repository navigation

🏷️ Adjust type annotation for Field.sa_type to support instantiated SQLAlchemy types - #1345

Closed
diachkow wants to merge 14 commits into
fastapi:mainfrom
diachkow:main
Closed

diachkow wants to merge 14 commits into
fastapi:mainfrom
diachkow:main

Conversation

diachkow commented Apr 21, 2025 •
edited by YuriiMotov
Loading

Copy link
Copy Markdown

Note

When I was writing description for this PR, I found another discussion started for just the same issue I was experiencing with mypy, so this changes are basically fixing the issue described here

Using sa_type and sa_column_kwargs instead of just sa_column can benefit when using inheritance for classes derived from SQLModel as it was suggested here.

If sa_column is not specified and sa_type is provided, it will be passed as a second, type argumnet to sqlalchemy.Column instance. If you would check sqlalchemy.Column construction definition, it looks as following:

    def __init__(
        self,
        __name_pos: Optional[
            Union[str, _TypeEngineArgument[_T], SchemaEventTarget]
        ] = None,
        __type_pos: Optional[
            Union[_TypeEngineArgument[_T], SchemaEventTarget]
        ] = None,
        *args: SchemaEventTarget,
        name: Optional[str] = None,
        type_: Optional[_TypeEngineArgument[_T]] = None,
        autoincrement: _AutoIncrementType = "auto",
        default: Optional[Any] = _NoArg.NO_ARG,
        insert_default: Optional[Any] = _NoArg.NO_ARG,
        doc: Optional[str] = None,
        key: Optional[str] = None,
        index: Optional[bool] = None,
        unique: Optional[bool] = None,
        info: Optional[_InfoType] = None,
        nullable: Optional[
            Union[bool, Literal[SchemaConst.NULL_UNSPECIFIED]]
        ] = SchemaConst.NULL_UNSPECIFIED,
        onupdate: Optional[Any] = None,
        primary_key: bool = False,
        server_default: Optional[_ServerDefaultArgument] = None,
        server_onupdate: Optional[_ServerOnUpdateArgument] = None,
        quote: Optional[bool] = None,
        system: bool = False,
        comment: Optional[str] = None,
        insert_sentinel: bool = False,
        _omit_from_statements: bool = False,
        _proxies: Optional[Any] = None,
        **dialect_kwargs: Any,
    ):

Note the __type_pos argument with Union[_TypeEngineArgument[_T], SchemaEventTarget] where

_TypeEngineArgument = Union[Type["TypeEngine[_T]"], "TypeEngine[_T]"]

So, from technical perspective you can pass not only the subclass of TypeEngine, e.g. SQLAlchemy's sqltype such as String, Integer, DateTime, JSON etc, but also an instance of this type.

I was trying for JSONB(none_as_null=True) and String(50) and it worked just fine, alembic migrations were generated correctly, only mypy was arguing for type mismatch with call-overload issue.

To fix mypy error, we can update type annotation for sqlmodel.main.Field.sa_type to support also an instantiated SQLAlchemy's sqltype to match those of sqlalchemy.Column

Related discussions:

This comment was marked as resolved.

svlandeg added the feature New feature or request label Apr 22, 2025

This comment was marked as resolved.

YuriiMotov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

LGTM

Simple code example to check (in the details)

Details
from datetime import datetime

from sqlmodel import DateTime, Field, SQLModel, create_engine

class A(SQLModel):
    created_at: datetime = Field(sa_type=DateTime(timezone=False))

engine = create_engine("sqlite:///")
SQLModel.metadata.create_all(engine)

Running mypy gives

error: No overload variant of "Field" matches argument type "DateTime"  [call-overload]

on master and

Success: no issues found in 1 source file

after applying this fix

Comment thread sqlmodel/main.py Outdated
YuriiMotov changed the title 🏷️ Adjust type annotation for Field.sa_type to support instantiated SQLAlchemy types 🏷️ Adjust type annotation for Field.sa_type to support instantiated SQLAlchemy types Aug 21, 2025
diachkow requested a review from YuriiMotov September 1, 2025 10:12

YuriiMotov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

LGTM
See #1345 (review)

diachkow commented Sep 2, 2025

Copy link
Copy Markdown
Author

Thanks for approval! Who is responsible for merging this, what are the rules in this repo?

Copy link
Copy Markdown
Member

Thanks for approval! Who is responsible for merging this, what are the rules in this repo?

Only Sebastian can merge it. I already forwarded it to him. We should just wait

github-actions Bot added the conflicts Automatically generated when a PR has a merge conflict label Dec 26, 2025

This comment was marked as resolved.

github-actions Bot removed the conflicts Automatically generated when a PR has a merge conflict label Dec 27, 2025

Copy link
Copy Markdown
Author

I have resolved conflicts here. I see you guys made some patch releases recently, hope this change can make it into one of them 🙃

This comment was marked as resolved.

github-actions Bot added the conflicts Automatically generated when a PR has a merge conflict label Jan 13, 2026
github-actions Bot removed the conflicts Automatically generated when a PR has a merge conflict label Jan 13, 2026
github-actions Bot added the conflicts Automatically generated when a PR has a merge conflict label Feb 20, 2026

This comment was marked as resolved.

github-actions Bot removed the conflicts Automatically generated when a PR has a merge conflict label Mar 3, 2026

This comment was marked as resolved.

github-actions Bot removed the conflicts Automatically generated when a PR has a merge conflict label Apr 3, 2026

Copy link
Copy Markdown

was hitting this error when using sa_type, thanks for keeping it updated

Copy link
Copy Markdown
Author

It would be nice to get it merged though 😅

Copy link
Copy Markdown

Hey @tiangolo, gently bumping this. It's been open about a year now, has an LGTM from @YuriiMotov, and @svlandeg mentioned back in September she'd forwarded it to you for merging.

To recap the issue:

  • Runtime is fine: sa_type already works correctly at runtime (SQLAlchemy accepts instantiated types like DateTime(timezone=False) just fine).
  • Typing is failing: The type annotation on Field.sa_type doesn't reflect that, so type checkers (basedpyright, zuban, mypy) flag valid code as an error.
  • Impact: It doesn't break anything at runtime, but it causes CI pipelines to fail.

Worth noting this is really a bug fix, not a feature. It's currently labeled as feature, but the code already does the right thing, this PR just corrects the type signature to match. Might be worth relabeling!

Totally understand if it's just buried under everything else, I didn't want it to get lost. Thanks for all the incredible work you do on FastAPI and SQLModel (and friends) :)

Copy link
Copy Markdown
Member

Thanks for the fix and for keeping this PR updated!

During final review, I found a subtle distinction: SQLAlchemy’s positional Column arguments also accept SchemaEventTarget for other schema objects, while sa_type should accept only SQLAlchemy type classes or instances.

I’ve put together #2095 with that narrower annotation, explicit type_ passing, and regression tests. It addresses the issue you identified here, so I’m closing this PR in favor of that implementation.

Thank you again for your contribution, and sorry this took so long to resolve! ☕

tiangolo closed this Sep 21, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants


Back | FazBrowse Home | New Git URL