GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Support hybrid_property, column_property, declared_attr by 50Bytes-dev · Pull Request #801 · fastapi/sqlmodel

Conversation

@50Bytes-dev

@50Bytes-dev 50Bytes-dev commented Feb 14, 2024

Copy link
Copy Markdown
    class Item(SQLModel, table=True):
        id: Optional[int] = Field(default=None, primary_key=True)
        value: float
        hero_id: int = Field(foreign_key="hero.id")
        hero: "Hero" = Relationship(back_populates="items")

    class Hero(SQLModel, table=True):
        id: Optional[int] = Field(default=None, primary_key=True)
        name: str
        items: list[Item] = Relationship(back_populates="hero")

        @hybrid_property
        def total_items(self):
            return sum([item.value for item in self.items], 0)

        @total_items.inplace.expression
        @classmethod
        def _total_items_expression(cls):
            return (
                select(func.coalesce(func.sum(Item.value), 0))
                .where(Item.hero_id == cls.id)
                .correlate(cls)
                .label("total_items")
            )

        @hybrid_property
        def status(self):
            return "active" if self.total_items > 0 else "inactive"

        @status.inplace.expression
        @classmethod
        def _status_expression(cls):
            return (
                select(case((cls.total_items > 0, "active"), else_="inactive"))
                .label("status")
            )

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

bschoenmaeckers, samidarko, lbowenwest, Matthieu-LAURENT39, marhoy, awoimbee, jkawczynski, evetness, AbelThorne, martinralfreindl, and 21 more reacted with thumbs up emoji
All reactions
  • 👍 31 reactions
50Bytes-dev and others added 6 commits February 14, 2024 15:36
@50Bytes-dev
Support hybrid_property
5471ece
@pre-commit-ci
🎨 [pre-commit.ci] Auto format from pre-commit.com hooks
c363ce6
@50Bytes-dev
fix
5bf07f8
@pre-commit-ci
🎨 [pre-commit.ci] Auto format from pre-commit.com hooks
224c74b
@50Bytes-dev
fix
3f82be3
@50Bytes-dev
Merge remote-tracking branch 'origin/main'
953c01d
This was referenced Feb 14, 2024
Using hybrid_property of SQLAlchemy leads to CompileError #299
Closed
How to create computed columns ? #150
Closed
✨ Add support for hybrid_property #482
Closed
@50Bytes-dev
add declared_attr, column_property support
e5dad94
@50Bytes-dev 50Bytes-dev changed the title Support hybrid_property Support hybrid_property, column_property, declared_attr Mar 1, 2024
pre-commit-ci Bot and others added 4 commits March 1, 2024 17:18
@pre-commit-ci
🎨 [pre-commit.ci] Auto format from pre-commit.com hooks
6bfff90
@50Bytes-dev
Merge branch 'tiangolo:main' into main
e5bb32a
@50Bytes-dev
fix tests
5ade49a
@50Bytes-dev
fix tests
b6e2caf
@50Bytes-dev

50Bytes-dev commented Mar 1, 2024

Copy link
Copy Markdown
Author
    class Item(SQLModel, table=True):
        id: Optional[int] = Field(default=None, primary_key=True)
        value: float
        hero_id: int = Field(foreign_key="hero.id")
        hero: "Hero" = Relationship(back_populates="items")

    class Hero(SQLModel, table=True):
        id: Optional[int] = Field(default=None, primary_key=True)
        name: str
        items: List[Item] = Relationship(back_populates="hero")

        @declared_attr
        def total_items(cls):
            return column_property(cls._total_items_expression())

        @classmethod
        def _total_items_expression(cls):
            return (
                select(func.coalesce(func.sum(Item.value), 0))
                .where(Item.hero_id == cls.id)
                .correlate_except(Item)
                .label("total_items")
            )

        @declared_attr
        def status(cls):
            return column_property(
                select(
                    case(
                        (cls._total_items_expression() > 0, "active"), else_="inactive"
                    )
                ).scalar_subquery()
            )
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@50Bytes-dev 50Bytes-dev mentioned this pull request Mar 1, 2024
Calculated columns not working (sqlaquemy.orm.column_property) #240
Closed
8 tasks done
awoimbee
awoimbee approved these changes Mar 7, 2024
View reviewed changes

@awoimbee awoimbee left a comment •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Just small suggestions from a random outsider :p (some suggestions might be wrong).
All in all, this is clean and adds a lot of functionality, thanks !
You should look into this @tiangolo !

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

50Bytes-dev and muazhari reacted with thumbs up emoji
All reactions
  • 👍 2 reactions
Comment thread sqlmodel/main.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread sqlmodel/main.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread sqlmodel/main.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread sqlmodel/main.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

50Bytes-dev and others added 3 commits March 7, 2024 17:18
@50Bytes-dev @awoimbee
Update sqlmodel/main.py
e0b201d
Co-authored-by: Arthur Woimbée <[email protected]>
@50Bytes-dev @awoimbee
Update sqlmodel/main.py
7ac7889
Co-authored-by: Arthur Woimbée <[email protected]>
@50Bytes-dev @awoimbee
Update sqlmodel/main.py
bb25d90
Co-authored-by: Arthur Woimbée <[email protected]>
@muazhari

muazhari commented Mar 22, 2024

Copy link
Copy Markdown

Please merge it asap :3. I need it, lol.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@mfkaroui

mfkaroui commented Mar 22, 2024

Copy link
Copy Markdown

hey can we get this merged in

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@mfkaroui

mfkaroui commented Apr 4, 2024

Copy link
Copy Markdown

@tiangolo Could you please take a look at this MR. The functionality is very nice. Would be a nice addition. Doesn't seem to clash with overall design

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@francomahl

francomahl commented Apr 15, 2024

Copy link
Copy Markdown
    class Item(SQLModel, table=True):
        id: Optional[int] = Field(default=None, primary_key=True)
        value: float
        hero_id: int = Field(foreign_key="hero.id")
        hero: "Hero" = Relationship(back_populates="items")

    class Hero(SQLModel, table=True):
        id: Optional[int] = Field(default=None, primary_key=True)
        name: str
        items: List[Item] = Relationship(back_populates="hero")

        @declared_attr
        def total_items(cls):
            return column_property(cls._total_items_expression())

        @classmethod
        def _total_items_expression(cls):
            return (
                select(func.coalesce(func.sum(Item.value), 0))
                .where(Item.hero_id == cls.id)
                .correlate_except(Item)
                .label("total_items")
            )

        @declared_attr
        def status(cls):
            return column_property(
                select(
                    case(
                        (cls._total_items_expression() > 0, "active"), else_="inactive"
                    )
                ).scalar_subquery()
            )

Following this example I am getting

pydantic.errors.PydanticUserError: A non-annotated attribute was detected: `total_items = <sqlalchemy.orm.decl_api.declared_attr object at 0x10e415350>`. All model fields require a type annotation; if `total_items` is not meant to be a field, you may be able to resolve this error by annotating it as a `ClassVar` or updating `model_config['ignored_types']`.

Even if I do def total_items(cls): -> int I still get the same error.
SQLModel version 0.0.16

But I think we can get the same result with computed_field and the property decorator

    from pydantic import computed_field

    class Hero(SQLModel, table=True):
        id: Optional[int] = Field(default=None, primary_key=True)
        name: str
        items: List[Item] = Relationship(back_populates="hero")

        @computed_field
        @property
        def total_items(cls) -> int:
            return len(self.items)
JulianBlin, raphaellaude, and arnab-mukherjee reacted with hooray emoji
All reactions
  • 🎉 3 reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@50Bytes-dev
Merge branch 'tiangolo:main' into main
8da2993
@raphaellaude

raphaellaude commented May 12, 2024

Copy link
Copy Markdown

Any movement to get this functionality in?

philippesamuel, themegaphoenix, staciax, MRocholl, jacm365, benjamin-texier, arnab-mukherjee, and jdalzatec reacted with thumbs up emoji
All reactions
  • 👍 8 reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

50Bytes-dev and others added 3 commits May 16, 2024 18:47
@50Bytes-dev
fix
7a53368
@pre-commit-ci
🎨 [pre-commit.ci] Auto format from pre-commit.com hooks
87d9c02
@50Bytes-dev
fix
0fa2d40
50Bytes-dev added 11 commits July 3, 2025 17:13
@50Bytes-dev
feat: enhance handling of association proxies in SQLModel initialization
170b343
@50Bytes-dev
chore: add pdm.lock and .pdm-python to .gitignore
c6f39f0
@50Bytes-dev
feat: add support for hybrid properties with setters in SQLModel and …
ddd0474
…enhance association proxy handling
@50Bytes-dev
feat: implement __sqlalchemy_hybrid_property_setters__ for hybrid pro…
0566470
…perties and enhance setter handling
@50Bytes-dev
feat: add deferred_column_property for safe deferred loading in SQLModel
e4a89e8
@50Bytes-dev
feat: enhance async handling in SafeDeferredColumnLoader and add test…
5d255c5
…s for fallback behavior
@50Bytes-dev
feat: implement SafeAttributeWrapper for improved async handling and …
ad7e957
…fallback values in deferred properties; add comprehensive tests for async scenarios and edge cases
@50Bytes-dev
feat: implement event-based fallback for deferred_column_property; ad…
4ea632a
…d tests to verify fallback behavior after refresh and loading
@50Bytes-dev
feat: refactor deferred_column_property to use standard ColumnPropert…
08e57d9
…y; add basic tests for fallback behavior and undefer functionality
@50Bytes-dev
feat: enhance deferred_column_property with additional parameters and…
8e9fe31
… typing tests for compatibility
@50Bytes-dev
feat: update col function to return QueryableAttribute for improved t…
5ff1e71
…ype safety
@sakost

sakost commented Aug 25, 2025

Copy link
Copy Markdown

any updates on this?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

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

github-actions Bot commented Sep 5, 2025

Copy link
Copy Markdown
Contributor

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

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@Vizonex

Vizonex commented Sep 25, 2025

Copy link
Copy Markdown

I think I can go a bit further than what this pr had in mind. I was thinking about combining computed_feilds and hybrid_property column_property and declared_attr together. Does anyone have any tips and suggestions? I'll try and use what this pr had in mind as a blueprint.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@50Bytes-dev
feat: refactor compatibility handling for Pydantic v2; introduce new …
e9c74ee
…configuration and utility functions for SQLModel
@Vizonex

Vizonex commented Oct 22, 2025

Copy link
Copy Markdown

@50Bytes-dev Glad to see your pr is still alive, mind if I help you review it?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

50Bytes-dev added 3 commits November 20, 2025 11:56
@50Bytes-dev
feat: add new utility functions for SQLModel to handle relations and …
a6db8af
…columns by schema; update col function to return InstrumentedAttribute for better type safety
@50Bytes-dev
feat: import new utility functions for handling columns by schema and…
fef15c5
… relations in SQLModel
@50Bytes-dev
feat: update validation_alias type in Field function to support Alias…
833b870
…Path and AliasChoices for enhanced flexibility
@Vizonex

Vizonex commented Nov 21, 2025

Copy link
Copy Markdown

@50Bytes-dev Have you tried adding some tests to the pytest to ensure that this implementation works?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@50Bytes-dev

50Bytes-dev commented Nov 21, 2025

Copy link
Copy Markdown
Author

@50Bytes-dev Have you tried adding some tests to the pytest to ensure that this implementation works?

Yes, I have basic tests. I use this PR in the production of my projects and make sure that everything works correctly.

Vizonex reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@tstorek

tstorek commented Nov 26, 2025

Copy link
Copy Markdown

@50Bytes-dev thanks, for that piece of code. Is there any chance for release some time soon. I have a use case starting from next week and I'd like to omit a vanilla sqlalchemy workaround :)

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@50Bytes-dev

50Bytes-dev commented Nov 26, 2025

Copy link
Copy Markdown
Author

@50Bytes-dev thanks, for that piece of code. Is there any chance for release some time soon. I have a use case starting from next week and I'd like to omit a vanilla sqlalchemy workaround :)

Release where? Personally, I just use the repository and don't plan to release anything anywhere. I recommend trying it this way too, it's quite convenient.

dependencies = [
  "sqlmodel",
]

[tool.uv.sources]
sqlmodel = { git = "https://github.com/50Bytes-dev/sqlmodel.git", rev = "833b8700e5006177d1a57fd8b3109bd625a358de" }
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@tstorek

tstorek commented Nov 26, 2025 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown

@50Bytes-dev Okay, sorry. I thought that the PR is meant to be merged at some point.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@50Bytes-dev

50Bytes-dev commented Nov 26, 2025

Copy link
Copy Markdown
Author

@50Bytes-dev Okay, sorry. I thought that the PR is meant to be merged at some point.

I think that the main repository is dead and unlikely to be developed further, so I created my own fork where I implement all the necessary functions myself.

Vizonex reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

50Bytes-dev added 2 commits November 30, 2025 15:10
@50Bytes-dev
fix: update type hints in col and relations functions to use Queryabl…
276cc1d
…eAttribute for better type safety
@50Bytes-dev
feat: add UnionEnum type decorator to handle multiple Enum types in S…
86451e7
…QLAlchemy fields
@ksaadDE

ksaadDE commented Jan 15, 2026

Copy link
Copy Markdown

I think that the main repository is dead

The main repo of what? FastAPI, SQLmodel?

If there is no PR, in SQLModel I assume, nobody can check it, thus it appears obv. dead. Though if you look at the commit history in main, all is fine

Looking for a method to introduce calculated column easily. Got to this to just read that lol

50Bytes-dev reacted with eyes emoji
All reactions
  • 👀 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@alvinttang alvinttang mentioned this pull request May 31, 2026
Allow hybrid_property, hybrid_method and association_proxy on SQLModel classes #1990
Open

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

1 more reviewer
@awoimbee awoimbee awoimbee approved these changes
Reviewers whose approvals may not affect merge requirements

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

conflicts Automatically generated when a PR has a merge conflict feature New feature or request

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

14 participants

@50Bytes-dev @muazhari @mfkaroui @francomahl @raphaellaude @irux @iliya-malecki @Zahlii @tstorek @sakost @Vizonex @ksaadDE @awoimbee @alejsdev
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.