Repository: litestar-org/litestar

Issue:
Bug: SQLAlchemyPlugin type detection not compatible with SQLAlchemy 2.0
For example:

```python-console
>>> from starlite import DTOFactory
>>> from starlite.plugins.sql_alchemy import SQLAlchemyPlugin
>>> dto_factory = DTOFactory(plugins=[SQLAlchemyPlugin()])
>>> UpdateAuthorDTO = dto_factory("UpdateAuthorDTO", Author, exclude=["created", "updated"])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.10/site-packages/starlite/dto.py", line 216, in __call__
    fields, plugin = self._get_fields_from_source(source)
  File "/usr/local/lib/python3.10/site-packages/starlite/dto.py", line 242, in _get_fields_from_source
    raise ImproperlyConfiguredException(
starlite.exceptions.http_exceptions.ImproperlyConfiguredException: 500: No supported plugin found for value <class 'app.domain.authors.Author'> - cannot create value
>>> type(Author)
<class 'sqlalchemy.orm.decl_api.DeclarativeAttributeIntercept'>
```



Discussion:

Resolving patch:
diff --git a/starlite/plugins/sql_alchemy/plugin.py b/starlite/plugins/sql_alchemy/plugin.py
--- a/starlite/plugins/sql_alchemy/plugin.py
+++ b/starlite/plugins/sql_alchemy/plugin.py
@@ -30,7 +30,8 @@
     from sqlalchemy import inspect
     from sqlalchemy import types as sqlalchemy_type
     from sqlalchemy.dialects import mssql, mysql, oracle, postgresql, sqlite
-    from sqlalchemy.orm import DeclarativeMeta, Mapper
+    from sqlalchemy.exc import NoInspectionAvailable
+    from sqlalchemy.orm import DeclarativeMeta, InstanceState, Mapper
     from sqlalchemy.sql.type_api import TypeEngine
 except ImportError as e:
     raise MissingDependencyException("sqlalchemy is not installed") from e
@@ -88,7 +89,11 @@ def is_plugin_supported_type(value: Any) -> "TypeGuard[DeclarativeMeta]":
         Returns:
             A boolean typeguard.
         """
-        return isinstance(value, DeclarativeMeta) or isinstance(value.__class__, DeclarativeMeta)
+        try:
+            inspected = inspect(value)
+        except NoInspectionAvailable:
+            return False
+        return isinstance(inspected, (Mapper, InstanceState))
 
     @staticmethod
     def handle_string_type(column_type: Union[sqlalchemy_type.String, sqlalchemy_type._Binary]) -> "Type":
@@ -329,13 +334,18 @@ def parse_model(model_class: DeclarativeMeta) -> Mapper:
             model_class: An SQLAlchemy declarative class.
 
         Returns:
-            An SQLAlchemy inspection 'Mapper'.
+            A SQLAlchemy `Mapper`.
         """
-        if not isinstance(model_class, DeclarativeMeta):
-            raise ImproperlyConfiguredException(
-                "Unsupported 'model_class' kwarg: only subclasses of the SQLAlchemy `DeclarativeMeta` are supported"
-            )
-        return inspect(model_class)
+        try:
+            inspected = inspect(model_class)
+        except NoInspectionAvailable:
+            pass
+        else:
+            if isinstance(inspected, Mapper):
+                return inspected
+        raise ImproperlyConfiguredException(
+            "Unsupported 'model_class' kwarg: only subclasses of the SQLAlchemy `DeclarativeMeta` are supported"
+        )
 
     def to_pydantic_model_class(self, model_class: Type[DeclarativeMeta], **kwargs: Any) -> "Type[BaseModel]":
         """Generates a pydantic model for a given SQLAlchemy declarative table


Test patch: