如何存储无纳秒的Firestore SERVER_TIMESTAMP,无需JsonEncoder适配FastAPI序列化?
解决Firestore DatetimeWithNanoseconds无法被FastAPI序列化的问题
方案1:读取数据时转换为标准datetime
从Firestore读取createTime后,直接将其转换为Python标准datetime对象,丢弃纳秒部分:
# 假设doc是从Firestore获取的文档快照 create_time = doc.to_dict()["createTime"] # 转换为标准datetime,去掉纳秒 standard_datetime = create_time.replace(tzinfo=None, microsecond=create_time.microsecond)
转换后的对象是FastAPI默认可序列化的标准datetime类型。
方案2:写入Firestore时直接存储标准datetime
放弃使用firestore.SERVER_TIMESTAMP,写入时生成不带纳秒的Python标准datetime:
from datetime import datetime import pytz # 生成带UTC时区的标准datetime(Firestore兼容该格式) create_time = datetime.now(tz=pytz.utc).replace(microsecond=0) # 写入Firestore db.collection("your_collection").add({ "createTime": create_time, # 其他字段 })
这种方式从根源上避免了纳秒类型的产生,读取后直接得到标准datetime,无需额外处理。
方案3:通过Pydantic模型自动转换
如果用Pydantic定义数据模型,可在字段校验环节完成类型转换:
from pydantic import BaseModel, field_validator from datetime import datetime class YourModel(BaseModel): createTime: datetime @field_validator("createTime", mode="before") def convert_datetime_with_nanoseconds(cls, v): if hasattr(v, 'replace'): return v.replace(tzinfo=None, microsecond=v.microsecond) return v
FastAPI处理请求或响应时,Pydantic会自动完成转换,无需全局配置JsonEncoder。
方案4:修改Firestore客户端的日期解析逻辑
通过自定义datetime_parser,让Firestore客户端直接返回标准datetime:
from google.cloud import firestore from datetime import datetime def parse_datetime_without_nanoseconds(value): dt = datetime.fromisoformat(value) return dt.replace(microsecond=dt.microsecond) # 初始化客户端时指定自定义解析器 db = firestore.Client() db._firestore_api.datetime_parser = parse_datetime_without_nanoseconds
该方式全局生效,所有从Firestore读取的日期都会被自动转换为标准datetime。
内容的提问来源于stack exchange,提问作者Prakhar Rathi
相关产品推荐
相关产品推荐

