You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FastAPI对接MongoDB启动报TypeError: %d格式需数字而非字符串

问题背景

我是Python初学者,正尝试开发一个从MongoDB数据库拉取数据的简易Web服务器,运行过程中遇到报错无法解决。

项目文件架构如下:
文件架构示意

项目原始代码
# Database
CONNECTION_URL = os.environ['mongoConnectionURL']
DATABASE_NAME = os.environ['mongoDatabaseName']
NEWS_COLLECTION = os.environ['mongodbNewsCollection']

app = FastAPI()

# TODO JS has next function i'm currently unaware of
app.add_middleware(
    CORSMiddleware,
    allow_origins=['*'],
    allow_headers=["Origin, X-Requested-With, Content-Type, Accept"],
)

@app.get('/')
def index():
    return 'See /entries'

@app.get('/entries')
def getEntries():
    client = MongoClient(CONNECTION_URL)
    databaseMongo = client.get_database(DATABASE_NAME)
    collectionMongo = databaseMongo.get_collection(NEWS_COLLECTION)
    result = list(collectionMongo.find())
    for entry in result:
        return {
            'data': result
        }

if __name__ == "__main__":
    uvicorn.run(app, port=os.environ['PORT'])
报错信息

运行时抛出的错误栈如下:

Traceback (most recent call last):
  File "/usr/local/lib/python3.9/logging/__init__.py", line 1083, in emit
    msg = self.format(record)
  File "/usr/local/lib/python3.9/logging/__init__.py", line 927, in format
    return fmt.format(record)
  File "/usr/local/lib/python3.9/logging/__init__.py", line 663, in format
    record.message = record.getMessage()
  File "/usr/local/lib/python3.9/logging/__init__.py", line 367, in getMessage
    msg = msg % self.args
TypeError: %d format: a number is required, not str

完整错误日志截图:
完整错误日志

报错原因与解决方案

核心报错原因

抛出该错误的直接原因是传入uvicorn的port参数类型错误:

  • os.environ读取到的所有环境变量值默认都是字符串类型
  • uvicorn内部启动日志打印监听端口时,使用了%d数字类型占位符格式化端口值,当拿到字符串类型的端口值时就会触发这个类型错误。

代码存在的其他问题

原始代码除了端口类型错误外,还有几处会影响运行的问题:

  • 缺少必要的模块导入语句,直接运行会触发NameError
  • CORS中间件的allow_headers配置格式错误,要求传入列表类型,原代码把所有请求头拼接成了单个字符串
  • /entries接口中存在无意义的for循环:遍历查询结果时第一次循环就直接return,循环逻辑完全多余
  • 每次接口请求都新建MongoDB客户端连接,会造成不必要的资源开销,高并发场景下会拖慢服务性能
  • MongoDB查询结果默认会携带_id字段(ObjectId类型),FastAPI默认无法序列化该类型,会触发后续的序列化报错

修正后可运行代码

import os
import uvicorn
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from pymongo import MongoClient

# 读取数据库配置环境变量
CONNECTION_URL = os.environ['mongoConnectionURL']
DATABASE_NAME = os.environ['mongoDatabaseName']
NEWS_COLLECTION = os.environ['mongodbNewsCollection']

app = FastAPI()

# 修正CORS中间件配置
app.add_middleware(
    CORSMiddleware,
    allow_origins=['*'],
    allow_headers=["*"],
    allow_methods=["*"]
)

# 全局初始化MongoDB连接,避免重复创建客户端
client = MongoClient(CONNECTION_URL)
db = client[DATABASE_NAME]
news_collection = db[NEWS_COLLECTION]

@app.get('/')
def index():
    return 'See /entries'

@app.get('/entries')
def get_entries():
    # 查询时排除_id字段,避免序列化报错
    result = list(news_collection.find({}, {"_id": 0}))
    return {"data": result}

if __name__ == "__main__":
    # 关键修正:将字符串类型的端口值转为整数
    uvicorn.run(app, port=int(os.environ['PORT']))

运行前检查项

  • 提前安装依赖:执行命令pip install fastapi uvicorn pymongo
  • 确认所有需要的环境变量都已正确配置:mongoConnectionURL、mongoDatabaseName、mongodbNewsCollection、PORT
  • 本地测试时可以直接在代码里写死配置验证逻辑,确认无问题后再切换为环境变量读取方式

内容的提问来源于stack exchange,提问作者cyruslk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 05:48:19