✨ Upgrade SQLAlchemy to 2.0, including initial work by farahats9 (#700)
Co-authored-by: Mohamed Farahat <farahats9@yahoo.com> Co-authored-by: Stefan Borer <stefan.borer@gmail.com> Co-authored-by: Peter Landry <peter.landry@gmail.com>
This commit is contained in:
committed by
GitHub
parent
77c6fed305
commit
8ed856d322
@@ -45,12 +45,19 @@ from sqlalchemy import (
|
||||
inspect,
|
||||
)
|
||||
from sqlalchemy import Enum as sa_Enum
|
||||
from sqlalchemy.orm import RelationshipProperty, declared_attr, registry, relationship
|
||||
from sqlalchemy.orm import (
|
||||
Mapped,
|
||||
RelationshipProperty,
|
||||
declared_attr,
|
||||
registry,
|
||||
relationship,
|
||||
)
|
||||
from sqlalchemy.orm.attributes import set_attribute
|
||||
from sqlalchemy.orm.decl_api import DeclarativeMeta
|
||||
from sqlalchemy.orm.instrumentation import is_instrumented
|
||||
from sqlalchemy.sql.schema import MetaData
|
||||
from sqlalchemy.sql.sqltypes import LargeBinary, Time
|
||||
from typing_extensions import get_origin
|
||||
|
||||
from .sql.sqltypes import GUID, AutoString
|
||||
|
||||
@@ -483,7 +490,16 @@ class SQLModelMetaclass(ModelMetaclass, DeclarativeMeta):
|
||||
# over anything else, use that and continue with the next attribute
|
||||
setattr(cls, rel_name, rel_info.sa_relationship) # Fix #315
|
||||
continue
|
||||
ann = cls.__annotations__[rel_name]
|
||||
raw_ann = cls.__annotations__[rel_name]
|
||||
origin = get_origin(raw_ann)
|
||||
if origin is Mapped:
|
||||
ann = raw_ann.__args__[0]
|
||||
else:
|
||||
ann = raw_ann
|
||||
# Plain forward references, for models not yet defined, are not
|
||||
# handled well by SQLAlchemy without Mapped, so, wrap the
|
||||
# annotations in Mapped here
|
||||
cls.__annotations__[rel_name] = Mapped[ann] # type: ignore[valid-type]
|
||||
temp_field = ModelField.infer(
|
||||
name=rel_name,
|
||||
value=rel_info,
|
||||
@@ -511,9 +527,7 @@ class SQLModelMetaclass(ModelMetaclass, DeclarativeMeta):
|
||||
rel_args.extend(rel_info.sa_relationship_args)
|
||||
if rel_info.sa_relationship_kwargs:
|
||||
rel_kwargs.update(rel_info.sa_relationship_kwargs)
|
||||
rel_value: RelationshipProperty = relationship( # type: ignore
|
||||
relationship_to, *rel_args, **rel_kwargs
|
||||
)
|
||||
rel_value = relationship(relationship_to, *rel_args, **rel_kwargs)
|
||||
setattr(cls, rel_name, rel_value) # Fix #315
|
||||
# SQLAlchemy no longer uses dict_
|
||||
# Ref: https://github.com/sqlalchemy/sqlalchemy/commit/428ea01f00a9cc7f85e435018565eb6da7af1b77
|
||||
@@ -642,6 +656,7 @@ class SQLModel(BaseModel, metaclass=SQLModelMetaclass, registry=default_registry
|
||||
__sqlmodel_relationships__: ClassVar[Dict[str, RelationshipProperty]] # type: ignore
|
||||
__name__: ClassVar[str]
|
||||
metadata: ClassVar[MetaData]
|
||||
__allow_unmapped__ = True # https://docs.sqlalchemy.org/en/20/changelog/migration_20.html#migration-20-step-six
|
||||
|
||||
class Config:
|
||||
orm_mode = True
|
||||
@@ -685,7 +700,7 @@ class SQLModel(BaseModel, metaclass=SQLModelMetaclass, registry=default_registry
|
||||
return
|
||||
else:
|
||||
# Set in SQLAlchemy, before Pydantic to trigger events and updates
|
||||
if getattr(self.__config__, "table", False) and is_instrumented(self, name):
|
||||
if getattr(self.__config__, "table", False) and is_instrumented(self, name): # type: ignore
|
||||
set_attribute(self, name, value)
|
||||
# Set in Pydantic model to trigger possible validation changes, only for
|
||||
# non relationship values
|
||||
|
||||
Reference in New Issue
Block a user