|
34 | 34 | from sqlalchemy import Boolean, Column, Date, DateTime |
35 | 35 | from sqlalchemy import Enum as sa_Enum |
36 | 36 | from sqlalchemy import Float, ForeignKey, Integer, Interval, Numeric, inspect |
| 37 | +from sqlalchemy.ext.hybrid import hybrid_property |
37 | 38 | from sqlalchemy.orm import RelationshipProperty, declared_attr, registry, relationship |
38 | 39 | from sqlalchemy.orm.attributes import set_attribute |
39 | 40 | from sqlalchemy.orm.decl_api import DeclarativeMeta |
@@ -290,7 +291,11 @@ def get_config(name: str) -> Any: |
290 | 291 | # If it was passed by kwargs, ensure it's also set in config |
291 | 292 | new_cls.__config__.table = config_table |
292 | 293 | for k, v in new_cls.__fields__.items(): |
293 | | - col = get_column_from_field(v) |
| 294 | + col = v |
| 295 | + # Treat `hybrid_property` properties as already specified columns |
| 296 | + # and let sqlalchemy take care of them |
| 297 | + if not issubclass(v.type_, hybrid_property): |
| 298 | + col = get_column_from_field(v) |
294 | 299 | setattr(new_cls, k, col) |
295 | 300 | # Set a config flag to tell FastAPI that this should be read with a field |
296 | 301 | # in orm_mode instead of preemptively converting it to a dict. |
@@ -326,6 +331,10 @@ def __init__( |
326 | 331 | if getattr(cls.__config__, "table", False) and not base_is_table: |
327 | 332 | dict_used = dict_.copy() |
328 | 333 | for field_name, field_value in cls.__fields__.items(): |
| 334 | + # Ignore `hybrid_property` properties as already specified columns |
| 335 | + # and let sqlalchemy take care of them |
| 336 | + if issubclass(field_value.type_, hybrid_property): |
| 337 | + continue |
329 | 338 | dict_used[field_name] = get_column_from_field(field_value) |
330 | 339 | for rel_name, rel_info in cls.__sqlmodel_relationships__.items(): |
331 | 340 | if rel_info.sa_relationship: |
|
0 commit comments