✨ Support Annotated approach for Relationship attributes - #1192

Open
bolu61 wants to merge 18 commits into
fastapi:mainfrom
bolu61:main
Open

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

Conversation

@bolu61

@bolu61bolu61 commented Oct 29, 2024

Copy link
Copy Markdown

see #229 (comment)

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

@svlandegsvlandeg added the feature New feature or request label Feb 24, 2025
@svlandegsvlandeg changed the title Add PEP 593 support for Requirement annotations✨ Add PEP 593 support for Requirement annotationsFeb 24, 2025

@YuriiMotovYuriiMotov 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.

@bolu61, thanks for working on this!

So, this PR fixes the following code example:

classFoo(SQLModel, table=True):
id: Annotated[int|None, Field(primary_key=True)] =Noneuuid: Annotated[UUID, Field(unique=True)]
classBar(SQLModel, table=True):
id: Annotated[int|None, Field(primary_key=True)] =Noneuuid: 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:

classHero(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

@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-actionsBot commented Nov 7, 2025

Copy link
Copy Markdown
Contributor

📝 Docs preview

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

@YuriiMotov

This comment was marked as resolved.

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

This comment was marked as resolved.

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

This comment was marked as resolved.

@github-actionsgithub-actionsBot removed the conflicts Automatically generated when a PR has a merge conflict label Mar 3, 2026
@svlandeg

Copy link
Copy Markdown
Member

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 YuriiMotovMarch 3, 2026 20:44

@YuriiMotovYuriiMotov 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.

This needs some more work and testing..

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

Comment threadsqlmodel/main.py Outdated
Comment threadsqlmodel/main.py Outdated
@bolu61

Copy link
Copy Markdown
Author

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

@github-actionsgithub-actionsBot added the conflicts Automatically generated when a PR has a merge conflict label Apr 5, 2026
@github-actions

Copy link
Copy Markdown
Contributor

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

@github-actions

Copy link
Copy Markdown
Contributor

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-actionsgithub-actionsBot removed the conflicts Automatically generated when a PR has a merge conflict label May 5, 2026
@bolu61
bolu61 requested a review from YuriiMotovMay 5, 2026 22:08
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

featureNew feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@bolu61@YuriiMotov@svlandeg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

✨ Support Annotated approach for Relationship attributes - #1192

Open
bolu61 wants to merge 18 commits into
fastapi:mainfrom
bolu61:main
Open

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

Conversation

@bolu61

@bolu61bolu61 commented Oct 29, 2024

Copy link
Copy Markdown

see #229 (comment)

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

@svlandegsvlandeg added the feature New feature or request label Feb 24, 2025
@svlandegsvlandeg changed the title Add PEP 593 support for Requirement annotations✨ Add PEP 593 support for Requirement annotationsFeb 24, 2025

@YuriiMotovYuriiMotov 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.

@bolu61, thanks for working on this!

So, this PR fixes the following code example:

classFoo(SQLModel, table=True):
id: Annotated[int|None, Field(primary_key=True)] =Noneuuid: Annotated[UUID, Field(unique=True)]
classBar(SQLModel, table=True):
id: Annotated[int|None, Field(primary_key=True)] =Noneuuid: 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:

classHero(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

@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-actionsBot commented Nov 7, 2025

Copy link
Copy Markdown
Contributor

📝 Docs preview

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

@YuriiMotov

This comment was marked as resolved.

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

This comment was marked as resolved.

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

This comment was marked as resolved.

@github-actionsgithub-actionsBot removed the conflicts Automatically generated when a PR has a merge conflict label Mar 3, 2026
@svlandeg

Copy link
Copy Markdown
Member

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 YuriiMotovMarch 3, 2026 20:44

@YuriiMotovYuriiMotov 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.

This needs some more work and testing..

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

Comment threadsqlmodel/main.py Outdated
Comment threadsqlmodel/main.py Outdated
@bolu61

Copy link
Copy Markdown
Author

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

@github-actionsgithub-actionsBot added the conflicts Automatically generated when a PR has a merge conflict label Apr 5, 2026
@github-actions

Copy link
Copy Markdown
Contributor

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

@github-actions

Copy link
Copy Markdown
Contributor

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-actionsgithub-actionsBot removed the conflicts Automatically generated when a PR has a merge conflict label May 5, 2026
@bolu61
bolu61 requested a review from YuriiMotovMay 5, 2026 22:08
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

featureNew feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@bolu61@YuriiMotov@svlandeg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

✨ Support Annotated approach for Relationship attributes - #1192

Open
bolu61 wants to merge 18 commits into
fastapi:mainfrom
bolu61:main
Open

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

Conversation

@bolu61

@bolu61bolu61 commented Oct 29, 2024

Copy link
Copy Markdown

see #229 (comment)

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

@svlandegsvlandeg added the feature New feature or request label Feb 24, 2025
@svlandegsvlandeg changed the title Add PEP 593 support for Requirement annotations✨ Add PEP 593 support for Requirement annotationsFeb 24, 2025

@YuriiMotovYuriiMotov 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.

@bolu61, thanks for working on this!

So, this PR fixes the following code example:

classFoo(SQLModel, table=True):
id: Annotated[int|None, Field(primary_key=True)] =Noneuuid: Annotated[UUID, Field(unique=True)]
classBar(SQLModel, table=True):
id: Annotated[int|None, Field(primary_key=True)] =Noneuuid: 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:

classHero(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

@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-actionsBot commented Nov 7, 2025

Copy link
Copy Markdown
Contributor

📝 Docs preview

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

@YuriiMotov

This comment was marked as resolved.

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

This comment was marked as resolved.

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

This comment was marked as resolved.

@github-actionsgithub-actionsBot removed the conflicts Automatically generated when a PR has a merge conflict label Mar 3, 2026
@svlandeg

Copy link
Copy Markdown
Member

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 YuriiMotovMarch 3, 2026 20:44

@YuriiMotovYuriiMotov 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.

This needs some more work and testing..

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

Comment threadsqlmodel/main.py Outdated
Comment threadsqlmodel/main.py Outdated
@bolu61

Copy link
Copy Markdown
Author

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

@github-actionsgithub-actionsBot added the conflicts Automatically generated when a PR has a merge conflict label Apr 5, 2026
@github-actions

Copy link
Copy Markdown
Contributor

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

@github-actions

Copy link
Copy Markdown
Contributor

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-actionsgithub-actionsBot removed the conflicts Automatically generated when a PR has a merge conflict label May 5, 2026
@bolu61
bolu61 requested a review from YuriiMotovMay 5, 2026 22:08
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

featureNew feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@bolu61@YuriiMotov@svlandeg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

✨ Support Annotated approach for Relationship attributes - #1192

Open
bolu61 wants to merge 18 commits into
fastapi:mainfrom
bolu61:main
Open

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

Conversation

@bolu61

@bolu61bolu61 commented Oct 29, 2024

Copy link
Copy Markdown

see #229 (comment)

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

@svlandegsvlandeg added the feature New feature or request label Feb 24, 2025
@svlandegsvlandeg changed the title Add PEP 593 support for Requirement annotations✨ Add PEP 593 support for Requirement annotationsFeb 24, 2025

@YuriiMotovYuriiMotov 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.

@bolu61, thanks for working on this!

So, this PR fixes the following code example:

classFoo(SQLModel, table=True):
id: Annotated[int|None, Field(primary_key=True)] =Noneuuid: Annotated[UUID, Field(unique=True)]
classBar(SQLModel, table=True):
id: Annotated[int|None, Field(primary_key=True)] =Noneuuid: 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:

classHero(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

@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-actionsBot commented Nov 7, 2025

Copy link
Copy Markdown
Contributor

📝 Docs preview

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

@YuriiMotov

This comment was marked as resolved.

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

This comment was marked as resolved.

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

This comment was marked as resolved.

@github-actionsgithub-actionsBot removed the conflicts Automatically generated when a PR has a merge conflict label Mar 3, 2026
@svlandeg

Copy link
Copy Markdown
Member

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 YuriiMotovMarch 3, 2026 20:44

@YuriiMotovYuriiMotov 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.

This needs some more work and testing..

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

Comment threadsqlmodel/main.py Outdated
Comment threadsqlmodel/main.py Outdated
@bolu61

Copy link
Copy Markdown
Author

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

@github-actionsgithub-actionsBot added the conflicts Automatically generated when a PR has a merge conflict label Apr 5, 2026
@github-actions

Copy link
Copy Markdown
Contributor

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

@github-actions

Copy link
Copy Markdown
Contributor

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-actionsgithub-actionsBot removed the conflicts Automatically generated when a PR has a merge conflict label May 5, 2026
@bolu61
bolu61 requested a review from YuriiMotovMay 5, 2026 22:08
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

featureNew feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@bolu61@YuriiMotov@svlandeg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

✨ Support Annotated approach for Relationship attributes - #1192

Open
bolu61 wants to merge 18 commits into
fastapi:mainfrom
bolu61:main
Open

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

Conversation

@bolu61

@bolu61bolu61 commented Oct 29, 2024

Copy link
Copy Markdown

see #229 (comment)

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

@svlandegsvlandeg added the feature New feature or request label Feb 24, 2025
@svlandegsvlandeg changed the title Add PEP 593 support for Requirement annotations✨ Add PEP 593 support for Requirement annotationsFeb 24, 2025

@YuriiMotovYuriiMotov 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.

@bolu61, thanks for working on this!

So, this PR fixes the following code example:

classFoo(SQLModel, table=True):
id: Annotated[int|None, Field(primary_key=True)] =Noneuuid: Annotated[UUID, Field(unique=True)]
classBar(SQLModel, table=True):
id: Annotated[int|None, Field(primary_key=True)] =Noneuuid: 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:

classHero(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

@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-actionsBot commented Nov 7, 2025

Copy link
Copy Markdown
Contributor

📝 Docs preview

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

@YuriiMotov

This comment was marked as resolved.

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

This comment was marked as resolved.

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

This comment was marked as resolved.

@github-actionsgithub-actionsBot removed the conflicts Automatically generated when a PR has a merge conflict label Mar 3, 2026
@svlandeg

Copy link
Copy Markdown
Member

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 YuriiMotovMarch 3, 2026 20:44

@YuriiMotovYuriiMotov 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.

This needs some more work and testing..

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

Comment threadsqlmodel/main.py Outdated
Comment threadsqlmodel/main.py Outdated
@bolu61

Copy link
Copy Markdown
Author

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

@github-actionsgithub-actionsBot added the conflicts Automatically generated when a PR has a merge conflict label Apr 5, 2026
@github-actions

Copy link
Copy Markdown
Contributor

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

@github-actions

Copy link
Copy Markdown
Contributor

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-actionsgithub-actionsBot removed the conflicts Automatically generated when a PR has a merge conflict label May 5, 2026
@bolu61
bolu61 requested a review from YuriiMotovMay 5, 2026 22:08
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

featureNew feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@bolu61@YuriiMotov@svlandeg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

✨ Support Annotated approach for Relationship attributes - #1192

Open
bolu61 wants to merge 18 commits into
fastapi:mainfrom
bolu61:main
Open

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

Conversation

@bolu61

@bolu61bolu61 commented Oct 29, 2024

Copy link
Copy Markdown

see #229 (comment)

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

@svlandegsvlandeg added the feature New feature or request label Feb 24, 2025
@svlandegsvlandeg changed the title Add PEP 593 support for Requirement annotations✨ Add PEP 593 support for Requirement annotationsFeb 24, 2025

@YuriiMotovYuriiMotov 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.

@bolu61, thanks for working on this!

So, this PR fixes the following code example:

classFoo(SQLModel, table=True):
id: Annotated[int|None, Field(primary_key=True)] =Noneuuid: Annotated[UUID, Field(unique=True)]
classBar(SQLModel, table=True):
id: Annotated[int|None, Field(primary_key=True)] =Noneuuid: 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:

classHero(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

@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-actionsBot commented Nov 7, 2025

Copy link
Copy Markdown
Contributor

📝 Docs preview

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

@YuriiMotov

This comment was marked as resolved.

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

This comment was marked as resolved.

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

This comment was marked as resolved.

@github-actionsgithub-actionsBot removed the conflicts Automatically generated when a PR has a merge conflict label Mar 3, 2026
@svlandeg

Copy link
Copy Markdown
Member

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 YuriiMotovMarch 3, 2026 20:44

@YuriiMotovYuriiMotov 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.

This needs some more work and testing..

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

Comment threadsqlmodel/main.py Outdated
Comment threadsqlmodel/main.py Outdated
@bolu61

Copy link
Copy Markdown
Author

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

@github-actionsgithub-actionsBot added the conflicts Automatically generated when a PR has a merge conflict label Apr 5, 2026
@github-actions

Copy link
Copy Markdown
Contributor

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

@github-actions

Copy link
Copy Markdown
Contributor

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-actionsgithub-actionsBot removed the conflicts Automatically generated when a PR has a merge conflict label May 5, 2026
@bolu61
bolu61 requested a review from YuriiMotovMay 5, 2026 22:08
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

featureNew feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@bolu61@YuriiMotov@svlandeg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

✨ Support Annotated approach for Relationship attributes - #1192

Open
bolu61 wants to merge 18 commits into
fastapi:mainfrom
bolu61:main
Open

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

Conversation

@bolu61

@bolu61bolu61 commented Oct 29, 2024

Copy link
Copy Markdown

see #229 (comment)

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

@svlandegsvlandeg added the feature New feature or request label Feb 24, 2025
@svlandegsvlandeg changed the title Add PEP 593 support for Requirement annotations✨ Add PEP 593 support for Requirement annotationsFeb 24, 2025

@YuriiMotovYuriiMotov 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.

@bolu61, thanks for working on this!

So, this PR fixes the following code example:

classFoo(SQLModel, table=True):
id: Annotated[int|None, Field(primary_key=True)] =Noneuuid: Annotated[UUID, Field(unique=True)]
classBar(SQLModel, table=True):
id: Annotated[int|None, Field(primary_key=True)] =Noneuuid: 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:

classHero(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

@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-actionsBot commented Nov 7, 2025

Copy link
Copy Markdown
Contributor

📝 Docs preview

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

@YuriiMotov

This comment was marked as resolved.

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

This comment was marked as resolved.

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

This comment was marked as resolved.

@github-actionsgithub-actionsBot removed the conflicts Automatically generated when a PR has a merge conflict label Mar 3, 2026
@svlandeg

Copy link
Copy Markdown
Member

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 YuriiMotovMarch 3, 2026 20:44

@YuriiMotovYuriiMotov 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.

This needs some more work and testing..

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

Comment threadsqlmodel/main.py Outdated
Comment threadsqlmodel/main.py Outdated
@bolu61

Copy link
Copy Markdown
Author

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

@github-actionsgithub-actionsBot added the conflicts Automatically generated when a PR has a merge conflict label Apr 5, 2026
@github-actions

Copy link
Copy Markdown
Contributor

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

@github-actions

Copy link
Copy Markdown
Contributor

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-actionsgithub-actionsBot removed the conflicts Automatically generated when a PR has a merge conflict label May 5, 2026
@bolu61
bolu61 requested a review from YuriiMotovMay 5, 2026 22:08
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

featureNew feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@bolu61@YuriiMotov@svlandeg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

✨ Support Annotated approach for Relationship attributes - #1192

Open
bolu61 wants to merge 18 commits into
fastapi:mainfrom
bolu61:main
Open

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

Conversation

@bolu61

@bolu61bolu61 commented Oct 29, 2024

Copy link
Copy Markdown

see #229 (comment)

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

@svlandegsvlandeg added the feature New feature or request label Feb 24, 2025
@svlandegsvlandeg changed the title Add PEP 593 support for Requirement annotations✨ Add PEP 593 support for Requirement annotationsFeb 24, 2025

@YuriiMotovYuriiMotov 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.

@bolu61, thanks for working on this!

So, this PR fixes the following code example:

classFoo(SQLModel, table=True):
id: Annotated[int|None, Field(primary_key=True)] =Noneuuid: Annotated[UUID, Field(unique=True)]
classBar(SQLModel, table=True):
id: Annotated[int|None, Field(primary_key=True)] =Noneuuid: 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:

classHero(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

@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-actionsBot commented Nov 7, 2025

Copy link
Copy Markdown
Contributor

📝 Docs preview

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

@YuriiMotov

This comment was marked as resolved.

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

This comment was marked as resolved.

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

This comment was marked as resolved.

@github-actionsgithub-actionsBot removed the conflicts Automatically generated when a PR has a merge conflict label Mar 3, 2026
@svlandeg

Copy link
Copy Markdown
Member

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 YuriiMotovMarch 3, 2026 20:44

@YuriiMotovYuriiMotov 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.

This needs some more work and testing..

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

Comment threadsqlmodel/main.py Outdated
Comment threadsqlmodel/main.py Outdated
@bolu61

Copy link
Copy Markdown
Author

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

@github-actionsgithub-actionsBot added the conflicts Automatically generated when a PR has a merge conflict label Apr 5, 2026
@github-actions

Copy link
Copy Markdown
Contributor

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

@github-actions

Copy link
Copy Markdown
Contributor

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-actionsgithub-actionsBot removed the conflicts Automatically generated when a PR has a merge conflict label May 5, 2026
@bolu61
bolu61 requested a review from YuriiMotovMay 5, 2026 22:08
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

featureNew feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@bolu61@YuriiMotov@svlandeg