diff --git a/docs_src/tutorial/fastapi/delete/tutorial001.py b/docs_src/tutorial/fastapi/delete/tutorial001.py index 3053300..f69e3ee 100644 --- a/docs_src/tutorial/fastapi/delete/tutorial001.py +++ b/docs_src/tutorial/fastapi/delete/tutorial001.py @@ -79,7 +79,7 @@ def update_hero(hero_id: int, hero: HeroUpdate): db_hero = session.get(Hero, hero_id) if not db_hero: raise HTTPException(status_code=404, detail="Hero not found") - hero_data = hero.dict(exclude_unset=True) + hero_data = hero.model_dump(exclude_unset=True) for key, value in hero_data.items(): setattr(db_hero, key, value) session.add(db_hero) diff --git a/sqlmodel/main.py b/sqlmodel/main.py index 8199226..141005f 100644 --- a/sqlmodel/main.py +++ b/sqlmodel/main.py @@ -236,7 +236,6 @@ class SQLModelMetaclass(ModelMetaclass, DeclarativeMeta): class_dict: Dict[str, Any], **kwargs: Any, ) -> Any: - relationships: Dict[str, RelationshipInfo] = {} dict_for_pydantic = {} original_annotations = class_dict.get("__annotations__", {}) @@ -569,7 +568,22 @@ class SQLModel(BaseModel, metaclass=SQLModelMetaclass, registry=default_registry validated = super().model_validate( obj, strict=strict, from_attributes=from_attributes, context=context ) - return cls(**{key: value for key, value in validated}) + + # remove defaults so they don't get validated + data = {} + for key, value in validated: + field = cls.model_fields[key] + + if ( + hasattr(field, "default") + and field.default is not PydanticUndefined + and value == field.default + ): + continue + + data[key] = value + + return cls(**data) def _is_field_noneable(field: FieldInfo) -> bool: diff --git a/sqlmodel/sql/expression.py b/sqlmodel/sql/expression.py index a0ac1bd..8cb2309 100644 --- a/sqlmodel/sql/expression.py +++ b/sqlmodel/sql/expression.py @@ -35,6 +35,14 @@ class SelectOfScalar(_Select[Tuple[_TSelect]], Generic[_TSelect]): inherit_cache = True +# This is not comparable to sqlalchemy.sql.selectable.ScalarSelect, that has a different +# purpose. This is the same as a normal SQLAlchemy Select class where there's only one +# entity, so the result will be converted to a scalar by default. This way writing +# for loops on the results will feel natural. +class SelectOfScalar(_Select, Generic[_TSelect]): + inherit_cache = True + + if TYPE_CHECKING: # pragma: no cover from ..main import SQLModel diff --git a/tests/test_default.py b/tests/test_default.py index cf61cf8..a2dd2f3 100644 --- a/tests/test_default.py +++ b/tests/test_default.py @@ -1,3 +1,5 @@ +from typing import Any + from sqlmodel.default import Default @@ -9,7 +11,7 @@ def test_default_bool() -> None: df1 = Default(False) df2 = Default(0) df3 = Default("") - df4: list = Default([]) + df4: list[Any] = Default([]) df5 = Default(None) assert not not dt1 diff --git a/tests/test_tutorial/test_fastapi/test_delete/test_tutorial001.py b/tests/test_tutorial/test_fastapi/test_delete/test_tutorial001.py index e560d04..bf27e77 100644 --- a/tests/test_tutorial/test_fastapi/test_delete/test_tutorial001.py +++ b/tests/test_tutorial/test_fastapi/test_delete/test_tutorial001.py @@ -3,7 +3,7 @@ from sqlmodel import create_engine from sqlmodel.pool import StaticPool openapi_schema = { - "openapi": "3.0.2", + "openapi": "3.1.0", "info": {"title": "FastAPI", "version": "0.1.0"}, "paths": { "/heroes/": { @@ -210,7 +210,10 @@ openapi_schema = { "properties": { "name": {"title": "Name", "type": "string"}, "secret_name": {"title": "Secret Name", "type": "string"}, - "age": {"title": "Age", "type": "integer"}, + "age": { + "title": "Age", + "anyOf": [{"type": "integer"}, {"type": "null"}], + }, }, }, "HeroRead": { @@ -220,7 +223,10 @@ openapi_schema = { "properties": { "name": {"title": "Name", "type": "string"}, "secret_name": {"title": "Secret Name", "type": "string"}, - "age": {"title": "Age", "type": "integer"}, + "age": { + "title": "Age", + "anyOf": [{"type": "integer"}, {"type": "null"}], + }, "id": {"title": "Id", "type": "integer"}, }, }, @@ -228,9 +234,18 @@ openapi_schema = { "title": "HeroUpdate", "type": "object", "properties": { - "name": {"title": "Name", "type": "string"}, - "secret_name": {"title": "Secret Name", "type": "string"}, - "age": {"title": "Age", "type": "integer"}, + "name": { + "title": "Name", + "anyOf": [{"type": "string"}, {"type": "null"}], + }, + "secret_name": { + "title": "Secret Name", + "anyOf": [{"type": "string"}, {"type": "null"}], + }, + "age": { + "title": "Age", + "anyOf": [{"type": "integer"}, {"type": "null"}], + }, }, }, "ValidationError": { @@ -241,7 +256,7 @@ openapi_schema = { "loc": { "title": "Location", "type": "array", - "items": {"type": "string"}, + "items": {"anyOf": [{"type": "string"}, {"type": "integer"}]}, }, "msg": {"title": "Message", "type": "string"}, "type": {"title": "Error Type", "type": "string"}, @@ -261,7 +276,6 @@ def test_tutorial(clear_sqlmodel): ) with TestClient(mod.app) as client: - hero1_data = {"name": "Deadpond", "secret_name": "Dive Wilson"} hero2_data = { "name": "Spider-Boy", diff --git a/tests/test_tutorial/test_fastapi/test_limit_and_offset/test_tutorial001.py b/tests/test_tutorial/test_fastapi/test_limit_and_offset/test_tutorial001.py index b58afdf..7a4958a 100644 --- a/tests/test_tutorial/test_fastapi/test_limit_and_offset/test_tutorial001.py +++ b/tests/test_tutorial/test_fastapi/test_limit_and_offset/test_tutorial001.py @@ -3,7 +3,7 @@ from sqlmodel import create_engine from sqlmodel.pool import StaticPool openapi_schema = { - "openapi": "3.0.2", + "openapi": "3.1.0", "info": {"title": "FastAPI", "version": "0.1.0"}, "paths": { "/heroes/": { @@ -142,7 +142,10 @@ openapi_schema = { "properties": { "name": {"title": "Name", "type": "string"}, "secret_name": {"title": "Secret Name", "type": "string"}, - "age": {"title": "Age", "type": "integer"}, + "age": { + "title": "Age", + "anyOf": [{"type": "integer"}, {"type": "null"}], + }, }, }, "HeroRead": { @@ -152,7 +155,10 @@ openapi_schema = { "properties": { "name": {"title": "Name", "type": "string"}, "secret_name": {"title": "Secret Name", "type": "string"}, - "age": {"title": "Age", "type": "integer"}, + "age": { + "title": "Age", + "anyOf": [{"type": "integer"}, {"type": "null"}], + }, "id": {"title": "Id", "type": "integer"}, }, }, @@ -164,7 +170,7 @@ openapi_schema = { "loc": { "title": "Location", "type": "array", - "items": {"type": "string"}, + "items": {"anyOf": [{"type": "string"}, {"type": "integer"}]}, }, "msg": {"title": "Message", "type": "string"}, "type": {"title": "Error Type", "type": "string"}, @@ -184,7 +190,6 @@ def test_tutorial(clear_sqlmodel): ) with TestClient(mod.app) as client: - hero1_data = {"name": "Deadpond", "secret_name": "Dive Wilson"} hero2_data = { "name": "Spider-Boy", diff --git a/tests/test_tutorial/test_fastapi/test_multiple_models/test_tutorial001.py b/tests/test_tutorial/test_fastapi/test_multiple_models/test_tutorial001.py index d05c4a2..cb4c8ce 100644 --- a/tests/test_tutorial/test_fastapi/test_multiple_models/test_tutorial001.py +++ b/tests/test_tutorial/test_fastapi/test_multiple_models/test_tutorial001.py @@ -5,7 +5,7 @@ from sqlmodel import create_engine from sqlmodel.pool import StaticPool openapi_schema = { - "openapi": "3.0.2", + "openapi": "3.1.0", "info": {"title": "FastAPI", "version": "0.1.0"}, "paths": { "/heroes/": { @@ -81,7 +81,10 @@ openapi_schema = { "properties": { "name": {"title": "Name", "type": "string"}, "secret_name": {"title": "Secret Name", "type": "string"}, - "age": {"title": "Age", "type": "integer"}, + "age": { + "title": "Age", + "anyOf": [{"type": "integer"}, {"type": "null"}], + }, }, }, "HeroRead": { @@ -92,7 +95,10 @@ openapi_schema = { "id": {"title": "Id", "type": "integer"}, "name": {"title": "Name", "type": "string"}, "secret_name": {"title": "Secret Name", "type": "string"}, - "age": {"title": "Age", "type": "integer"}, + "age": { + "title": "Age", + "anyOf": [{"type": "integer"}, {"type": "null"}], + }, }, }, "ValidationError": { @@ -103,7 +109,7 @@ openapi_schema = { "loc": { "title": "Location", "type": "array", - "items": {"type": "string"}, + "items": {"anyOf": [{"type": "string"}, {"type": "integer"}]}, }, "msg": {"title": "Message", "type": "string"}, "type": {"title": "Error Type", "type": "string"}, @@ -123,7 +129,6 @@ def test_tutorial(clear_sqlmodel): ) with TestClient(mod.app) as client: - hero1_data = {"name": "Deadpond", "secret_name": "Dive Wilson"} hero2_data = { "name": "Spider-Boy", diff --git a/tests/test_tutorial/test_fastapi/test_multiple_models/test_tutorial002.py b/tests/test_tutorial/test_fastapi/test_multiple_models/test_tutorial002.py index a8b5b7b..d208876 100644 --- a/tests/test_tutorial/test_fastapi/test_multiple_models/test_tutorial002.py +++ b/tests/test_tutorial/test_fastapi/test_multiple_models/test_tutorial002.py @@ -5,7 +5,7 @@ from sqlmodel import create_engine from sqlmodel.pool import StaticPool openapi_schema = { - "openapi": "3.0.2", + "openapi": "3.1.0", "info": {"title": "FastAPI", "version": "0.1.0"}, "paths": { "/heroes/": { @@ -81,7 +81,10 @@ openapi_schema = { "properties": { "name": {"title": "Name", "type": "string"}, "secret_name": {"title": "Secret Name", "type": "string"}, - "age": {"title": "Age", "type": "integer"}, + "age": { + "title": "Age", + "anyOf": [{"type": "integer"}, {"type": "null"}], + }, }, }, "HeroRead": { @@ -91,7 +94,10 @@ openapi_schema = { "properties": { "name": {"title": "Name", "type": "string"}, "secret_name": {"title": "Secret Name", "type": "string"}, - "age": {"title": "Age", "type": "integer"}, + "age": { + "title": "Age", + "anyOf": [{"type": "integer"}, {"type": "null"}], + }, "id": {"title": "Id", "type": "integer"}, }, }, @@ -103,7 +109,7 @@ openapi_schema = { "loc": { "title": "Location", "type": "array", - "items": {"type": "string"}, + "items": {"anyOf": [{"type": "string"}, {"type": "integer"}]}, }, "msg": {"title": "Message", "type": "string"}, "type": {"title": "Error Type", "type": "string"}, @@ -123,7 +129,6 @@ def test_tutorial(clear_sqlmodel): ) with TestClient(mod.app) as client: - hero1_data = {"name": "Deadpond", "secret_name": "Dive Wilson"} hero2_data = { "name": "Spider-Boy", diff --git a/tests/test_tutorial/test_fastapi/test_read_one/test_tutorial001.py b/tests/test_tutorial/test_fastapi/test_read_one/test_tutorial001.py index 5b3c771..78a39f9 100644 --- a/tests/test_tutorial/test_fastapi/test_read_one/test_tutorial001.py +++ b/tests/test_tutorial/test_fastapi/test_read_one/test_tutorial001.py @@ -3,7 +3,7 @@ from sqlmodel import create_engine from sqlmodel.pool import StaticPool openapi_schema = { - "openapi": "3.0.2", + "openapi": "3.1.0", "info": {"title": "FastAPI", "version": "0.1.0"}, "paths": { "/heroes/": { @@ -113,7 +113,10 @@ openapi_schema = { "properties": { "name": {"title": "Name", "type": "string"}, "secret_name": {"title": "Secret Name", "type": "string"}, - "age": {"title": "Age", "type": "integer"}, + "age": { + "title": "Age", + "anyOf": [{"type": "integer"}, {"type": "null"}], + }, }, }, "HeroRead": { @@ -123,7 +126,10 @@ openapi_schema = { "properties": { "name": {"title": "Name", "type": "string"}, "secret_name": {"title": "Secret Name", "type": "string"}, - "age": {"title": "Age", "type": "integer"}, + "age": { + "title": "Age", + "anyOf": [{"type": "integer"}, {"type": "null"}], + }, "id": {"title": "Id", "type": "integer"}, }, }, @@ -135,7 +141,7 @@ openapi_schema = { "loc": { "title": "Location", "type": "array", - "items": {"type": "string"}, + "items": {"anyOf": [{"type": "string"}, {"type": "integer"}]}, }, "msg": {"title": "Message", "type": "string"}, "type": {"title": "Error Type", "type": "string"}, @@ -155,7 +161,6 @@ def test_tutorial(clear_sqlmodel): ) with TestClient(mod.app) as client: - hero1_data = {"name": "Deadpond", "secret_name": "Dive Wilson"} hero2_data = { "name": "Spider-Boy", diff --git a/tests/test_tutorial/test_fastapi/test_relationships/test_tutorial001.py b/tests/test_tutorial/test_fastapi/test_relationships/test_tutorial001.py index 125e001..4d35b7c 100644 --- a/tests/test_tutorial/test_fastapi/test_relationships/test_tutorial001.py +++ b/tests/test_tutorial/test_fastapi/test_relationships/test_tutorial001.py @@ -3,7 +3,7 @@ from sqlmodel import create_engine from sqlmodel.pool import StaticPool openapi_schema = { - "openapi": "3.0.2", + "openapi": "3.1.0", "info": {"title": "FastAPI", "version": "0.1.0"}, "paths": { "/heroes/": { @@ -397,8 +397,14 @@ openapi_schema = { "properties": { "name": {"title": "Name", "type": "string"}, "secret_name": {"title": "Secret Name", "type": "string"}, - "age": {"title": "Age", "type": "integer"}, - "team_id": {"title": "Team Id", "type": "integer"}, + "age": { + "title": "Age", + "anyOf": [{"type": "integer"}, {"type": "null"}], + }, + "team_id": { + "title": "Team Id", + "anyOf": [{"type": "integer"}, {"type": "null"}], + }, }, }, "HeroRead": { @@ -408,8 +414,14 @@ openapi_schema = { "properties": { "name": {"title": "Name", "type": "string"}, "secret_name": {"title": "Secret Name", "type": "string"}, - "age": {"title": "Age", "type": "integer"}, - "team_id": {"title": "Team Id", "type": "integer"}, + "age": { + "title": "Age", + "anyOf": [{"type": "integer"}, {"type": "null"}], + }, + "team_id": { + "title": "Team Id", + "anyOf": [{"type": "integer"}, {"type": "null"}], + }, "id": {"title": "Id", "type": "integer"}, }, }, @@ -420,20 +432,43 @@ openapi_schema = { "properties": { "name": {"title": "Name", "type": "string"}, "secret_name": {"title": "Secret Name", "type": "string"}, - "age": {"title": "Age", "type": "integer"}, - "team_id": {"title": "Team Id", "type": "integer"}, + "age": { + "title": "Age", + "anyOf": [{"type": "integer"}, {"type": "null"}], + }, + "team_id": { + "title": "Team Id", + "anyOf": [{"type": "integer"}, {"type": "null"}], + }, "id": {"title": "Id", "type": "integer"}, - "team": {"$ref": "#/components/schemas/TeamRead"}, + "team": { + "anyOf": [ + {"$ref": "#/components/schemas/TeamRead"}, + {"type": "null"}, + ] + }, }, }, "HeroUpdate": { "title": "HeroUpdate", "type": "object", "properties": { - "name": {"title": "Name", "type": "string"}, - "secret_name": {"title": "Secret Name", "type": "string"}, - "age": {"title": "Age", "type": "integer"}, - "team_id": {"title": "Team Id", "type": "integer"}, + "name": { + "title": "Name", + "anyOf": [{"type": "string"}, {"type": "null"}], + }, + "secret_name": { + "title": "Secret Name", + "anyOf": [{"type": "string"}, {"type": "null"}], + }, + "age": { + "title": "Age", + "anyOf": [{"type": "integer"}, {"type": "null"}], + }, + "team_id": { + "title": "Team Id", + "anyOf": [{"type": "integer"}, {"type": "null"}], + }, }, }, "TeamCreate": { @@ -475,9 +510,18 @@ openapi_schema = { "title": "TeamUpdate", "type": "object", "properties": { - "id": {"title": "Id", "type": "integer"}, - "name": {"title": "Name", "type": "string"}, - "headquarters": {"title": "Headquarters", "type": "string"}, + "id": { + "title": "Id", + "anyOf": [{"type": "integer"}, {"type": "null"}], + }, + "name": { + "title": "Name", + "anyOf": [{"type": "string"}, {"type": "null"}], + }, + "headquarters": { + "title": "Headquarters", + "anyOf": [{"type": "string"}, {"type": "null"}], + }, }, }, "ValidationError": { @@ -488,7 +532,7 @@ openapi_schema = { "loc": { "title": "Location", "type": "array", - "items": {"type": "string"}, + "items": {"anyOf": [{"type": "string"}, {"type": "integer"}]}, }, "msg": {"title": "Message", "type": "string"}, "type": {"title": "Error Type", "type": "string"}, diff --git a/tests/test_tutorial/test_fastapi/test_response_model/test_tutorial001.py b/tests/test_tutorial/test_fastapi/test_response_model/test_tutorial001.py index 54fbbdc..6cbf35a 100644 --- a/tests/test_tutorial/test_fastapi/test_response_model/test_tutorial001.py +++ b/tests/test_tutorial/test_fastapi/test_response_model/test_tutorial001.py @@ -3,7 +3,7 @@ from sqlmodel import create_engine from sqlmodel.pool import StaticPool openapi_schema = { - "openapi": "3.0.2", + "openapi": "3.1.0", "info": {"title": "FastAPI", "version": "0.1.0"}, "paths": { "/heroes/": { @@ -74,13 +74,18 @@ openapi_schema = { }, "Hero": { "title": "Hero", - "required": ["name", "secret_name"], "type": "object", "properties": { - "id": {"title": "Id", "type": "integer"}, + "id": { + "title": "Id", + "anyOf": [{"type": "integer"}, {"type": "null"}], + }, "name": {"title": "Name", "type": "string"}, "secret_name": {"title": "Secret Name", "type": "string"}, - "age": {"title": "Age", "type": "integer"}, + "age": { + "title": "Age", + "anyOf": [{"type": "integer"}, {"type": "null"}], + }, }, }, "ValidationError": { @@ -91,7 +96,9 @@ openapi_schema = { "loc": { "title": "Location", "type": "array", - "items": {"type": "string"}, + "items": { + "anyOf": [{"type": "string"}, {"type": "integer"}], + }, }, "msg": {"title": "Message", "type": "string"}, "type": {"title": "Error Type", "type": "string"}, @@ -111,7 +118,6 @@ def test_tutorial(clear_sqlmodel): ) with TestClient(mod.app) as client: - hero_data = {"name": "Deadpond", "secret_name": "Dive Wilson"} response = client.post("/heroes/", json=hero_data) data = response.json() diff --git a/tests/test_tutorial/test_fastapi/test_session_with_dependency/test_tutorial001.py b/tests/test_tutorial/test_fastapi/test_session_with_dependency/test_tutorial001.py index d8dbe3f..1f2f292 100644 --- a/tests/test_tutorial/test_fastapi/test_session_with_dependency/test_tutorial001.py +++ b/tests/test_tutorial/test_fastapi/test_session_with_dependency/test_tutorial001.py @@ -3,7 +3,7 @@ from sqlmodel import create_engine from sqlmodel.pool import StaticPool openapi_schema = { - "openapi": "3.0.2", + "openapi": "3.1.0", "info": {"title": "FastAPI", "version": "0.1.0"}, "paths": { "/heroes/": { @@ -210,7 +210,10 @@ openapi_schema = { "properties": { "name": {"title": "Name", "type": "string"}, "secret_name": {"title": "Secret Name", "type": "string"}, - "age": {"title": "Age", "type": "integer"}, + "age": { + "title": "Age", + "anyOf": [{"type": "integer"}, {"type": "null"}], + }, }, }, "HeroRead": { @@ -220,7 +223,10 @@ openapi_schema = { "properties": { "name": {"title": "Name", "type": "string"}, "secret_name": {"title": "Secret Name", "type": "string"}, - "age": {"title": "Age", "type": "integer"}, + "age": { + "title": "Age", + "anyOf": [{"type": "integer"}, {"type": "null"}], + }, "id": {"title": "Id", "type": "integer"}, }, }, @@ -228,9 +234,18 @@ openapi_schema = { "title": "HeroUpdate", "type": "object", "properties": { - "name": {"title": "Name", "type": "string"}, - "secret_name": {"title": "Secret Name", "type": "string"}, - "age": {"title": "Age", "type": "integer"}, + "name": { + "title": "Name", + "anyOf": [{"type": "string"}, {"type": "null"}], + }, + "secret_name": { + "title": "Secret Name", + "anyOf": [{"type": "string"}, {"type": "null"}], + }, + "age": { + "title": "Age", + "anyOf": [{"type": "integer"}, {"type": "null"}], + }, }, }, "ValidationError": { @@ -241,7 +256,9 @@ openapi_schema = { "loc": { "title": "Location", "type": "array", - "items": {"type": "string"}, + "items": { + "anyOf": [{"type": "string"}, {"type": "integer"}], + }, }, "msg": {"title": "Message", "type": "string"}, "type": {"title": "Error Type", "type": "string"}, @@ -261,7 +278,6 @@ def test_tutorial(clear_sqlmodel): ) with TestClient(mod.app) as client: - hero1_data = {"name": "Deadpond", "secret_name": "Dive Wilson"} hero2_data = { "name": "Spider-Boy", diff --git a/tests/test_tutorial/test_fastapi/test_simple_hero_api/test_tutorial001.py b/tests/test_tutorial/test_fastapi/test_simple_hero_api/test_tutorial001.py index 2f87faf..f4d4feb 100644 --- a/tests/test_tutorial/test_fastapi/test_simple_hero_api/test_tutorial001.py +++ b/tests/test_tutorial/test_fastapi/test_simple_hero_api/test_tutorial001.py @@ -3,7 +3,7 @@ from sqlmodel import create_engine from sqlmodel.pool import StaticPool openapi_schema = { - "openapi": "3.0.2", + "openapi": "3.1.0", "info": {"title": "FastAPI", "version": "0.1.0"}, "paths": { "/heroes/": { @@ -62,13 +62,18 @@ openapi_schema = { }, "Hero": { "title": "Hero", - "required": ["name", "secret_name"], "type": "object", "properties": { - "id": {"title": "Id", "type": "integer"}, + "id": { + "title": "Id", + "anyOf": [{"type": "integer"}, {"type": "null"}], + }, "name": {"title": "Name", "type": "string"}, "secret_name": {"title": "Secret Name", "type": "string"}, - "age": {"title": "Age", "type": "integer"}, + "age": { + "title": "Age", + "anyOf": [{"type": "integer"}, {"type": "null"}], + }, }, }, "ValidationError": { @@ -79,7 +84,9 @@ openapi_schema = { "loc": { "title": "Location", "type": "array", - "items": {"type": "string"}, + "items": { + "anyOf": [{"type": "string"}, {"type": "integer"}], + }, }, "msg": {"title": "Message", "type": "string"}, "type": {"title": "Error Type", "type": "string"}, @@ -99,7 +106,6 @@ def test_tutorial(clear_sqlmodel): ) with TestClient(mod.app) as client: - hero1_data = {"name": "Deadpond", "secret_name": "Dive Wilson"} hero2_data = { "name": "Spider-Boy", diff --git a/tests/test_tutorial/test_fastapi/test_teams/test_tutorial001.py b/tests/test_tutorial/test_fastapi/test_teams/test_tutorial001.py index 6ac1cff..5261d2a 100644 --- a/tests/test_tutorial/test_fastapi/test_teams/test_tutorial001.py +++ b/tests/test_tutorial/test_fastapi/test_teams/test_tutorial001.py @@ -3,7 +3,7 @@ from sqlmodel import create_engine from sqlmodel.pool import StaticPool openapi_schema = { - "openapi": "3.0.2", + "openapi": "3.1.0", "info": {"title": "FastAPI", "version": "0.1.0"}, "paths": { "/heroes/": { @@ -393,8 +393,14 @@ openapi_schema = { "properties": { "name": {"title": "Name", "type": "string"}, "secret_name": {"title": "Secret Name", "type": "string"}, - "age": {"title": "Age", "type": "integer"}, - "team_id": {"title": "Team Id", "type": "integer"}, + "age": { + "title": "Age", + "anyOf": [{"type": "integer"}, {"type": "null"}], + }, + "team_id": { + "title": "Team Id", + "anyOf": [{"type": "integer"}, {"type": "null"}], + }, }, }, "HeroRead": { @@ -404,8 +410,14 @@ openapi_schema = { "properties": { "name": {"title": "Name", "type": "string"}, "secret_name": {"title": "Secret Name", "type": "string"}, - "age": {"title": "Age", "type": "integer"}, - "team_id": {"title": "Team Id", "type": "integer"}, + "age": { + "title": "Age", + "anyOf": [{"type": "integer"}, {"type": "null"}], + }, + "team_id": { + "title": "Team Id", + "anyOf": [{"type": "integer"}, {"type": "null"}], + }, "id": {"title": "Id", "type": "integer"}, }, }, @@ -413,10 +425,22 @@ openapi_schema = { "title": "HeroUpdate", "type": "object", "properties": { - "name": {"title": "Name", "type": "string"}, - "secret_name": {"title": "Secret Name", "type": "string"}, - "age": {"title": "Age", "type": "integer"}, - "team_id": {"title": "Team Id", "type": "integer"}, + "name": { + "title": "Name", + "anyOf": [{"type": "string"}, {"type": "null"}], + }, + "secret_name": { + "title": "Secret Name", + "anyOf": [{"type": "string"}, {"type": "null"}], + }, + "age": { + "title": "Age", + "anyOf": [{"type": "integer"}, {"type": "null"}], + }, + "team_id": { + "title": "Team Id", + "anyOf": [{"type": "integer"}, {"type": "null"}], + }, }, }, "TeamCreate": { @@ -442,8 +466,14 @@ openapi_schema = { "title": "TeamUpdate", "type": "object", "properties": { - "name": {"title": "Name", "type": "string"}, - "headquarters": {"title": "Headquarters", "type": "string"}, + "name": { + "title": "Name", + "anyOf": [{"type": "string"}, {"type": "null"}], + }, + "headquarters": { + "title": "Headquarters", + "anyOf": [{"type": "string"}, {"type": "null"}], + }, }, }, "ValidationError": { @@ -454,7 +484,9 @@ openapi_schema = { "loc": { "title": "Location", "type": "array", - "items": {"type": "string"}, + "items": { + "anyOf": [{"type": "string"}, {"type": "integer"}], + }, }, "msg": {"title": "Message", "type": "string"}, "type": {"title": "Error Type", "type": "string"}, @@ -474,7 +506,6 @@ def test_tutorial(clear_sqlmodel): ) with TestClient(mod.app) as client: - hero1_data = {"name": "Deadpond", "secret_name": "Dive Wilson"} hero2_data = { "name": "Spider-Boy", diff --git a/tests/test_tutorial/test_fastapi/test_update/test_tutorial001.py b/tests/test_tutorial/test_fastapi/test_update/test_tutorial001.py index e622fd3..2e7d8ea 100644 --- a/tests/test_tutorial/test_fastapi/test_update/test_tutorial001.py +++ b/tests/test_tutorial/test_fastapi/test_update/test_tutorial001.py @@ -3,7 +3,7 @@ from sqlmodel import create_engine from sqlmodel.pool import StaticPool openapi_schema = { - "openapi": "3.0.2", + "openapi": "3.1.0", "info": {"title": "FastAPI", "version": "0.1.0"}, "paths": { "/heroes/": { @@ -182,7 +182,10 @@ openapi_schema = { "properties": { "name": {"title": "Name", "type": "string"}, "secret_name": {"title": "Secret Name", "type": "string"}, - "age": {"title": "Age", "type": "integer"}, + "age": { + "title": "Age", + "anyOf": [{"type": "integer"}, {"type": "null"}], + }, }, }, "HeroRead": { @@ -192,7 +195,10 @@ openapi_schema = { "properties": { "name": {"title": "Name", "type": "string"}, "secret_name": {"title": "Secret Name", "type": "string"}, - "age": {"title": "Age", "type": "integer"}, + "age": { + "title": "Age", + "anyOf": [{"type": "integer"}, {"type": "null"}], + }, "id": {"title": "Id", "type": "integer"}, }, }, @@ -200,9 +206,18 @@ openapi_schema = { "title": "HeroUpdate", "type": "object", "properties": { - "name": {"title": "Name", "type": "string"}, - "secret_name": {"title": "Secret Name", "type": "string"}, - "age": {"title": "Age", "type": "integer"}, + "name": { + "title": "Name", + "anyOf": [{"type": "string"}, {"type": "null"}], + }, + "secret_name": { + "title": "Secret Name", + "anyOf": [{"type": "string"}, {"type": "null"}], + }, + "age": { + "title": "Age", + "anyOf": [{"type": "integer"}, {"type": "null"}], + }, }, }, "ValidationError": { @@ -213,7 +228,9 @@ openapi_schema = { "loc": { "title": "Location", "type": "array", - "items": {"type": "string"}, + "items": { + "anyOf": [{"type": "string"}, {"type": "integer"}], + }, }, "msg": {"title": "Message", "type": "string"}, "type": {"title": "Error Type", "type": "string"}, @@ -233,7 +250,6 @@ def test_tutorial(clear_sqlmodel): ) with TestClient(mod.app) as client: - hero1_data = {"name": "Deadpond", "secret_name": "Dive Wilson"} hero2_data = { "name": "Spider-Boy",