1414 ForwardRef ,
1515 List ,
1616 Mapping ,
17+ NoneType ,
1718 Optional ,
1819 Sequence ,
1920 Set ,
@@ -194,7 +195,7 @@ def Relationship(
194195 * ,
195196 back_populates : Optional [str ] = None ,
196197 link_model : Optional [Any ] = None ,
197- sa_relationship : Optional [RelationshipProperty ] = None ,
198+ sa_relationship : Optional [RelationshipProperty [ Any ] ] = None ,
198199 sa_relationship_args : Optional [Sequence [Any ]] = None ,
199200 sa_relationship_kwargs : Optional [Mapping [str , Any ]] = None ,
200201) -> Any :
@@ -211,7 +212,7 @@ def Relationship(
211212@__dataclass_transform__ (kw_only_default = True , field_descriptors = (Field , FieldInfo ))
212213class SQLModelMetaclass (ModelMetaclass , DeclarativeMeta ):
213214 __sqlmodel_relationships__ : Dict [str , RelationshipInfo ]
214- model_config : Type [ SQLModelConfig ]
215+ model_config : SQLModelConfig
215216 model_fields : Dict [str , FieldInfo ]
216217
217218 # Replicate SQLAlchemy
@@ -280,7 +281,9 @@ def __new__(
280281 if dict_used .get (key , PydanticUndefined ) is PydanticUndefined :
281282 dict_used [key ] = None
282283
283- new_cls = super ().__new__ (cls , name , bases , dict_used , ** config_kwargs )
284+ new_cls : Type ["SQLModelMetaclass" ] = super ().__new__ (
285+ cls , name , bases , dict_used , ** config_kwargs
286+ )
284287 new_cls .__annotations__ = {
285288 ** relationship_annotations ,
286289 ** pydantic_annotations ,
@@ -371,7 +374,7 @@ def __init__(
371374 rel_args .extend (rel_info .sa_relationship_args )
372375 if rel_info .sa_relationship_kwargs :
373376 rel_kwargs .update (rel_info .sa_relationship_kwargs )
374- rel_value : RelationshipProperty = relationship (
377+ rel_value : RelationshipProperty [ Any ] = relationship (
375378 relationship_to , * rel_args , ** rel_kwargs
376379 )
377380 dict_used [rel_name ] = rel_value
@@ -382,7 +385,8 @@ def __init__(
382385
383386
384387def get_sqlalchemy_type (field : FieldInfo ) -> Any :
385- type_ = field .annotation
388+ type_ : type | None = field .annotation
389+
386390 # Resolve Optional fields
387391 if type_ is not None and get_origin (type_ ) is Union :
388392 bases = get_args (type_ )
@@ -394,9 +398,12 @@ def get_sqlalchemy_type(field: FieldInfo) -> Any:
394398
395399 # The 3rd is PydanticGeneralMetadata
396400 metadata = _get_field_metadata (field )
401+ if type_ is None :
402+ raise ValueError ("Missing field type" )
397403 if issubclass (type_ , str ):
398- if getattr (metadata , "max_length" , None ):
399- return AutoString (length = metadata .max_length )
404+ max_length = getattr (metadata , "max_length" , None )
405+ if max_length :
406+ return AutoString (length = max_length )
400407 return AutoString
401408 if issubclass (type_ , float ):
402409 return Float
@@ -463,7 +470,7 @@ def get_column_from_field(field: FieldInfo) -> Column: # type: ignore
463470 "index" : index ,
464471 "unique" : unique ,
465472 }
466- sa_default = PydanticUndefined
473+ sa_default : PydanticUndefinedType | Callable [[], Any ] = PydanticUndefined
467474 if field .default_factory :
468475 sa_default = field .default_factory
469476 elif field .default is not PydanticUndefined :
@@ -483,14 +490,12 @@ def get_column_from_field(field: FieldInfo) -> Column: # type: ignore
483490
484491default_registry = registry ()
485492
486- _TSQLModel = TypeVar ("_TSQLModel" , bound = "SQLModel" )
487-
488493
489494class SQLModel (BaseModel , metaclass = SQLModelMetaclass , registry = default_registry ):
490495 # SQLAlchemy needs to set weakref(s), Pydantic will set the other slots values
491496 __slots__ = ("__weakref__" ,)
492497 __tablename__ : ClassVar [Union [str , Callable [..., str ]]]
493- __sqlmodel_relationships__ : ClassVar [Dict [str , RelationshipProperty ]]
498+ __sqlmodel_relationships__ : ClassVar [Dict [str , RelationshipProperty [ Any ] ]]
494499 __name__ : ClassVar [str ]
495500 metadata : ClassVar [MetaData ]
496501 __allow_unmapped__ = True # https://docs.sqlalchemy.org/en/20/changelog/migration_20.html#migration-20-step-six
@@ -511,7 +516,7 @@ def __setattr__(self, name: str, value: Any) -> None:
511516 return
512517 else :
513518 # Set in SQLAlchemy, before Pydantic to trigger events and updates
514- if self .model_config .get ("table" , False ) and is_instrumented (self , name ):
519+ if self .model_config .get ("table" , False ) and is_instrumented (self , name ): # type: ignore
515520 set_attribute (self , name , value )
516521 # Set in Pydantic model to trigger possible validation changes, only for
517522 # non relationship values
@@ -529,11 +534,11 @@ def __tablename__(cls) -> str:
529534
530535def _is_field_noneable (field : FieldInfo ) -> bool :
531536 if not field .is_required ():
532- if field .annotation is None or field .annotation is type ( None ) :
537+ if field .annotation is None or field .annotation is NoneType :
533538 return True
534539 if get_origin (field .annotation ) is Union :
535540 for base in get_args (field .annotation ):
536- if base is type ( None ) :
541+ if base is NoneType :
537542 return True
538543 return False
539544 return False
0 commit comments