当前位置: 首页 > 知识库问答 >
问题:

如何从FastAPIendpoint(Python)返回生成器/映射对象?

穆子琪
2023-03-14

我正在开发我的第一个FastAPI和Pydantic项目,在尝试从endpoint返回生成器时遇到了一个问题。问题在下面,任何投入都将不胜感激!

我有一个 API endpoint,我首先从数据库中获取数据记录,然后使用 map 函数格式化每条记录。但是,将映射结果返回到终结点时,键值映射出错。请注意,出于性能考虑(大数据量),我想将endpoint的返回类型保留为生成器。

我的伪代码:

@app.get("/records", response_model=Iterable[RecordModel])
async def get_records() -> Iterable[RecordModel]:
    # {queried_records} is a generator returned from the database query
    queried_records = get_records_from_database() 
    formatted_records = map(lambda record: __format(record), queried_records)
    return formatted_records

async def __format(queried_record: Dict[str, Union[str, HttpUrl]) -> Union[RecordModel, None]:
    formatted_record = RecordModel(
        key_1 = queried_record[key_a],
        key_2 = queried_record[key_b],
        key_3 = queried_record[key_c]
    )
    return formatted_record

这样,我在运行endpoint时出错

ValueError: [ValueError('dictionary update sequence element #0 has length 3; 2 is required'), TypeError('vars() argument must have __dict__ attribute')]

如果我__format方法更改为

async def __format(queried_record: Dict[str, Union[str, HttpUrl]) -> Union[RecordModel, None]:
    formatted_record = RecordModel(
        key_1 = queried_record[key_a],
        key_2 = queried_record[key_b]
    )
    return formatted_record

从Swagger UI中,我可以看到endpoint被执行

{ key_1: key_2 }

很奇怪,我花了相当长的时间调试,但无法整理出来。如何修复上面提到的ValueError?非常感谢您的预先投入!

共有2个答案

焦宏硕
2023-03-14
    < li >当格式为异步时,您应该等待它或只删除异步 < li>Swagger (OpenAPI)告诉您它将返回什么,因为response _ model = Iterable[record model]它并不意味着这就是您将实际返回的内容 < li >您可以使用列表理解,而不是< code >映射 < li >在响应模型< code>RecordModel中,您可以从删除它开始。然后API会返回。 < ul > < li >但是,这样你会大摇大摆地丢失一些文档 < li >另一个解决方案是检查(并修正)模型是否真正符合您返回的内容。
@app.get("/records")
async def get_records() -> Iterable[RecordModel]: return [
    __format(record) for record 
    in get_records_from_database()
]

def __format(
    queried_record: Dict[str, Union[str, HttpUrl]
) -> Union[RecordModel, None]: return RecordModel(
    key_1 = queried_record[key_a],
    key_2 = queried_record[key_b],
    key_3 = queried_record[key_c]
)    
仲孙默
2023-03-14

经过一段时间的修改,虽然我仍然没有解决上面文章中提到的<code>ValueError</code>,但我找到了一个解决方法——在处理数据库大查询时,使用分页查询而不是返回生成器作为查询结果。

如此改进和有效的伪代码:

@app.get("/records", response_model=List[RecordModel])
async def get_records(
    offset: int = 0, # start position of the query
    limit: int = 1000 # size of the query
) -> List[RecordModel]:
    queried_records = get_records_from_database(offset, limit) 
    formatted_records = map(lambda record: __format(record), queried_records)
    return list(formatted_records)

def __format(queried_record: Dict[str, Union[str, HttpUrl]) -> Union[RecordModel, None]:
    formatted_record = RecordModel(
        key_1 = queried_record[key_a],
        key_2 = queried_record[key_b],
        key_3 = queried_record[key_c]
    )
    return formatted_record

通过这种方式,我将使用分页处理大型数据库查询的责任交给了API用户。

 类似资料:
  • 我试图使用MapStruct在dto和实体对象之间映射convert,但是生成的映射器实现只返回空的映射对象。 BeermapperImpl 任何人都可以提供我的代码可能出错的地方?谢谢!

  • 我使用pyodbc和pandas-read_-sql从Oracle数据库中提取数据。 当我进入这一行时,我没有看到任何错误 但是当我试着看的时候 我得到这个错误 我对这一错误的含义或可能的原因进行了研究,但没有得出令人满意的答案。 使用chunksize的原因是我有一个包含6000万行的Oracle db表,并计划以位的形式下载,然后将它们放在一起,就像这里:如何从sql查询创建一个大数据帧而不耗

  • 我的问题可以通过下面的(简化的)例子得到最好的描述: 给定一个异步HTTP客户端,该客户端返回<code>Future 对资源A执行GET 一旦GET完成,就对资源B执行GET 我的具体问题是,如何从映射器中返回未来,而资源B必须为 返回一个< code>Future,而< code>Future#map方法希望我传递一个从提供的值同步映射的映射器。 从JavaScript世界的< code>Pr

  • 问题内容: 我目前正在尝试制作一个将动词与西班牙语共轭的程序。我创建了一个哈希表,其中包含一个键和对象Ve​​rb的实例化。键是具有动词不定式形式的字符串(例如“ hablar”)。这是到目前为止我对哈希映射的代码: HashMap中每个动词的键都基于动词的不定式形式。例如,字符串“ hablar”是西班牙语动词的键。Verb类具有一个名为getInfinitive()的方法,该方法返回一个字符串

  • 问题内容: 我有两个C#类 和 在dbContext调用中使用它,以通过EF5映射数据库中的返回对象 我遇到的问题是,即使返回了地址数据,我似乎也无法获得映射的地址对象。searchResult映射的其他属性很好。 问题答案: SqlQuery不支持 您应该做的是:

  • 是否有方法重写build方法返回SampleClass以避免执行build.build?