Pandas Not a Time (NaT) value raises TypeError when being converted into a <datetime | None> column type using model_validate() #1734
-
First Check
Commit to Help
Example Codefrom sqlmodel import SQLModel, Field
from datetime import datetime
import pandas as pd
from fastapi import FastAPI
# HeroMeeting has a nullable datetime field called "time"
class HeroMeeting(SQLModel):
id : int | None = Field(primary_key=True, default=None)
name : str = Field(max_length=255, default=None)
time : datetime | None = Field(default=None)
app = FastAPI()
# Create a list of HeroMeeting entries, one of which has datetime set to None
hero_meetings = [
{"name": "Cape Repair Workshop", "time": datetime(day=7, month=2, year=2022)},
{"name": "Night Owl Patrol", "time": datetime(day=10, month=2, year=2022)},
{"name": "Budget Villain Confrontation", "time": datetime(day=12, month=2, year=2022)},
{"name": "Secret Lair Lease Inspection", "time": datetime(day=15, month=2, year=2022)},
{"name": "Moral Ambiguity Training", "time": datetime(day=18, month=2, year=2022)},
{"name": "Bootleg Justice League AGM", "time": datetime(day=20, month=2, year=2022)},
{"name": "Midnight Mask Exchange", "time": None},
]
# Convert list of HeroMeeting entries into a Pandas DataFrame and back
hero_meetings = pd.DataFrame(hero_meetings)
hero_meetings = hero_meetings.to_dict(orient="records")
@app.post("/get_first_hero_meeting", response_model = HeroMeeting)
def get_first_hero_meeting():
# WILL NOT raise exception because the datetime is assigned
return HeroMeeting.model_validate(hero_meetings[0])
@app.post("/get_last_hero_meeting", response_model = HeroMeeting)
def get_last_hero_meeting():
# WILL raise exception because the datetime has been converted from None to Not a Time (NaT) by Pandas, which is not correctly converted to NONE by SQLAlchemy
return HeroMeeting.model_validate(hero_meetings[-1])
@app.post("/get_hero_meetings", response_model = list[HeroMeeting])
def get_hero_meetings():
meetings = []
for meeting in hero_meetings:
# WILL raise an exception once it reaches a meeting with an unset time
meeting = HeroMeeting.model_validate(meeting)
meetings.append(meeting)
return meetingsDescription
Cause
Workaround
@app.post("/get_hero_meetings", response_model = list[HeroMeeting])
def get_hero_meetings():
meetings = []
for meeting in hero_meetings:
# FIX: Explicitly convert Not a Time (NaT) back to None.
if pd.isna(meeting["time"]): meeting["time"] = None
meeting = HeroMeeting.model_validate(meeting)
meetings.append(meeting)
return meetingsOperating SystemLinux Operating System DetailsLinux nixos 6.12.59 #1-NixOS SMP PREEMPT_DYNAMIC Mon Nov 24 09:36:08 UTC 2025 x86_64 GNU/Linux SQLModel Version0.0.24 Python Version3.12.12 Additional ContextUsing pandas 2.3.1 |
Beta Was this translation helpful? Give feedback.
Answered by
YuriiMotov
Feb 3, 2026
Replies: 1 comment 1 reply
-
|
Does it work with pure Pydantic model? |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I checked it works the same way with Pydantic model. So, it's not an SQLModel's issue.
You can solve this by adding a
field_validatorto conbertNaTtoNone: