Skip to content

✨ Support Annotated approach for Relationship attributes#1192

Open
bolu61 wants to merge 18 commits intofastapi:mainfrom
bolu61:main
Open

✨ Support Annotated approach for Relationship attributes#1192
bolu61 wants to merge 18 commits intofastapi:mainfrom
bolu61:main

Conversation

@bolu61
Copy link
Copy Markdown

@bolu61 bolu61 commented Oct 29, 2024

see #229 (comment)

I'm not really sure how Pydantic does it, but here's a potential workaround to the problem.

@svlandeg svlandeg added the feature New feature or request label Feb 24, 2025
@svlandeg svlandeg changed the title Add PEP 593 support for Requirement annotations ✨ Add PEP 593 support for Requirement annotations Feb 24, 2025
Copy link
Copy Markdown
Member

@YuriiMotov YuriiMotov left a comment

Choose a reason for hiding this comment

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

@bolu61, thanks for working on this!

So, this PR fixes the following code example:

class Foo(SQLModel, table=True):
    id: Annotated[int | None, Field(primary_key=True)] = None
    uuid: Annotated[UUID, Field(unique=True)]

class Bar(SQLModel, table=True):
    id: Annotated[int | None, Field(primary_key=True)] = None
    uuid: Annotated[UUID, Field(unique=True)]
    foo_id: Annotated[int, Field(foreign_key="foo.id")]
    foo: Annotated[Foo, Relationship()]

For now last line (with Relationship()) doesn't work (ValueError: <class '__main__.Foo'> has no matching SQLAlchemy type) and this PR fixes that.

I think this is not the same that was initially proposed in #229. The idea there was to support passing multiple annotations like:

class Hero(SQLModel, table=True):
    id: Annotated[Optional[int], Field(examples=....), Column(primary_key=True)] = None

Where Field can be pydantic.Field.
So, I suggest we unmark this PR as the one that resolves that issue.

As for changes introduced by this PR, I think it goes in line with modern recommendations to use Annotated approach instead parameterizing fields via default value.
I think we should test this approach more and add some automatic tests. Then it will have all chances to be accepted.

@bolu61
Copy link
Copy Markdown
Author

bolu61 commented Sep 11, 2025

@YuriiMotov I agree.

I'm not too familiar with this codebase. Can you point me to where I can write those tests?

@YuriiMotov
Copy link
Copy Markdown
Member

I'm not too familiar with this codebase. Can you point me to where I can write those tests?

You can create an annotated version of the code example from "Relationships" section of docs:

@github-actions

This comment was marked as outdated.

@bolu61

This comment was marked as resolved.

@github-actions github-actions Bot removed the waiting label Nov 7, 2025
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Nov 7, 2025

📝 Docs preview

Last commit 9302e61 at: https://7e0c97b3.sqlmodel.pages.dev

@YuriiMotov

This comment was marked as resolved.

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

This comment was marked as resolved.

@YuriiMotov YuriiMotov changed the title ✨ Add PEP 593 support for Requirement annotations ✨ Support Annotated approach for Relationship attributes Jan 26, 2026
@YuriiMotov

This comment was marked as resolved.

@github-actions github-actions Bot removed the conflicts Automatically generated when a PR has a merge conflict label Mar 3, 2026
@svlandeg
Copy link
Copy Markdown
Member

svlandeg commented Mar 3, 2026

The test that was failing previously is now fixed thanks to #1607.

@YuriiMotov : do you want to give this another review?

@svlandeg svlandeg requested a review from YuriiMotov March 3, 2026 20:44
Copy link
Copy Markdown
Member

@YuriiMotov YuriiMotov left a comment

Choose a reason for hiding this comment

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

This needs some more work and testing..

@bolu61, would you like to continue working on this?

Comment thread sqlmodel/main.py Outdated
Comment thread sqlmodel/main.py Outdated
@bolu61
Copy link
Copy Markdown
Author

bolu61 commented Mar 4, 2026

Ofc. Might take me some time to reread the rest of the code though.

@github-actions github-actions Bot removed the waiting label Mar 4, 2026
@github-actions github-actions Bot added the conflicts Automatically generated when a PR has a merge conflict label Apr 5, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 5, 2026

This pull request has a merge conflict that needs to be resolved.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 3, 2026

Heads-up: this will be closed in 3 days unless there's new activity.

bolu61 added 2 commits May 5, 2026 16:21
- Detect annotated relationships without a default value by iterating
  over the union of class_dict and original_annotations.
- Use elif and unwrap inner Mapped[T] when handling Annotated[Mapped[T], ...]
  to avoid double-wrapping in Mapped.
- Split the relationship/pydantic partition into three single-purpose
  loops with comments for clarity.
- Add tests covering Annotated relationships with default value, without
  default value, and with Annotated[Mapped[T], ...].
@github-actions github-actions Bot removed the conflicts Automatically generated when a PR has a merge conflict label May 5, 2026
@bolu61 bolu61 requested a review from YuriiMotov May 5, 2026 22:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New feature or request waiting

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants