我的编程空间,编程开发者的网络收藏夹
学习永远不晚

pydantic如何使用

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

pydantic如何使用

这篇“pydantic如何使用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“pydantic如何使用”文章吧。

pydantic是一个Python的数据验证和转换库,它的特点是轻量、快速、可扩展、可配置。笔者常用的用于数据接口schema定义与检查。

当前现状

在项目中,pydantic的定义是在数据的出口进行规范化,从而使得下游接受方能更快地去解析和清洗这些数据。

from pydantic import BaseModel, Field# 定义数据模型class Project(BaseModel):    url: str = Field(...)    title: str = Field(...)    content: str = Field(...)    company: List[Dict] = Field(default=[])    industry: str = Field(...)

以上是简单的一个数据模型定义,代码仅为示例,隐去了一些字段和配置。也就是我们必须传输给Project模型对应的数据才可以通过它的数据校验,否则就无法继续向下(可能是发往下游)

这么做一直以来没什么问题,直到本次项目中的接口返回出现了大更新,使得之前的所有代码层做的数据字段映射必须重新对应匹配。

比如之前title字段对应的是title,现在变成了detail-article-title

这使得我们必须在代码层做诸如:

# project_data均为接口返回的数据,加数据演示# 之前的代码project_data = {    "url": "https://www.baidu.com",    "title": "百度一下,你就知道",}project = Project(    **project_data)# 现在的代码project_data = {  "detail": {      "url": "xxx"      "article": {          "title": "项目标题",      }  }}project = Project(    url=project_data["detail"]["url"],    title=project_data["detail"]["article"]["title"],)

以上代码取值变得复杂,这还没考虑到数据可能存在出错的问题,比如detail字段不存在,这样就会导致KeyError异常。

而且这并不是夸张的举例(因为事实情况更复杂)。

我怎么能容忍这种情况呢?

解决方案

我当然不是想摒弃掉pydantic,而是想找到一种结合它更优雅的方式来解决这个问题。

于是我第一时间想到了jmespath模块,因为它是一个JSON查询语言,可以用来在JSON数据中查找和提取数据。

from jmespath import searchproject_data = {    "detail": {        "article": {            "title": "项目标题",        }    }}title = search("detail.article.title", project_data)assert title == "项目标题"  # True# 即使是path不存在,也不会异常,而是返回Noneassert search("detail.article.title1", project_data) is None  # True

所以我打算做一个结合pydanticjmespath的方式来解决这个问题。

class Project(BaseModel):    url: str = Field(...)    title: str = Field(...)    content: str = Field(...)    company: List[Dict] = Field(default=[])    industry: str = Field(...)    @root_validator(pre=True, skip_on_failure=True)    def data_converter(cls, v):        return {            "url": search("detail.id", v),            "title": search("detail.article.title", v),            "content": search("detail.article.content", v),            "company": search("company[*].name", v),            "industry": search("industry", v)        }        @validator("url")    def url_validator(cls, v):        # 由于这里的v是拿到的ID,需要组合成url        return f"https://xxxxx/{v}"

从代码中可以知道,我是在root_validator中提前做了数据的转换,将jmespath的查询结果赋值给对应的字段。

但是做完之后我越看越变扭,我为了做这个事情,先要申明所有字段,还要对这些字段一一映射。

于是,我想到了pydanticConfig类,它可以用来配置pydantic的一些行为。而且通过查看源码,我认为我可以通过Field类中输入一个path变量,告诉未来的处理器,这个path是用来做数据提取的。

class Project(BaseModel):    url: str = Field(..., path="temporaryLibrary.id")    company_names: str = Field(..., path="company[0].enterprise.name")    versions: List[str] = Field(..., path="versionList[*].id")

当然现在代码是没有任何意义的,因为path是我们自定义的,pydantic并不知道如何处理它。

所以下一步我们要做的是,如何更好的让pydantic知道如何处理path

在多次翻阅它源代码,并结合官方文档中对Model类的介绍,我找到了一个可行的方案。

Pydantic models can be created from arbitrary class instances to support models that map to ORM objects.

也就是说,我可以将原始数据通过from_orm传递给pydantic的模型,然后通过Data binding的方式,将数据绑定到模型中。Data binding允许我们自定义数据的取值来源。

class ProjectGetter(GetterDict):    def get(self, key: str, default: Any) -> Any:  # noqa        # 由于getter_dict所能拿到的“数据权限”相对较低,        # 也就是它的权限仅仅是处理数据,而不是处理模型,        # 所以我们需要自己去拿到模型,然后再去拿到path        model, data = self._obj['model'], self._obj['data']        for name, field in model.__fields__.items():            path = field.field_info.extra.get('path')            if path and name == key:                return search(path, data)        return defaultclass Project(BaseModel):    url: str = Field(..., path="detail.id")    company_names: str = Field(..., path="company[0].enterprise.name")    versions: List[str] = Field(..., path="versionList[*].id")    @validator("url")    def url_validator(cls, v):        return f"https://www.baidu.com/{v}"    class Config:        # 通过orm_mode指定数据的来源        orm_mode = True        # 通过getter_dict指定数据的获取方式        getter_dict = ProjectGetterproject_data = {    "detail": {        "id": 1,        "article": {            "title": "项目标题",        }    },    "company": [      {        "enterprise": {          "name": "企业名称1"        }      },      {        "enterprise": {          "name": "企业名称2"        }      }    ],    "versionList": [{"id": "1.0"}, {"id": "2.0"}]}project = Project.from_orm({"model": Project, "data": project_data})print(project)# url='https://www.baidu.com/1' company_names='企业名称1' versions=['1.0', '2.0']

这样我们在业务端,只需要对Field指定其对应数据提取的path,而不需要再去写一堆的validator或者是在数据进入前做一堆的数据转换。

以上就是关于“pydantic如何使用”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注编程网行业资讯频道。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

pydantic如何使用

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

pydantic如何使用

这篇“pydantic如何使用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“pydantic如何使用”文章吧。pydanti
2023-07-05

crystaldiskinforh如何使用

这篇文章主要介绍“crystaldiskinforh如何使用”,在日常操作中,相信很多人在crystaldiskinforh如何使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”crystaldiskinfo
2023-02-09

pandas如何使用

小编给大家分享一下pandas如何使用,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、生成数据表 1、首先导入pandas库,一般都会用到numpy库,所以我们
2023-06-02

Nmap如何使用

本篇内容介绍了“Nmap如何使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Nmap(Network Mapper)是一款开放源代码的网络
2023-06-27

wget如何使用

这篇文章主要讲解了“wget如何使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“wget如何使用”吧!wget 是一个从网络上自动下载文件的自由工具,支持通过 HTTP、HTTPS、FTP
2023-06-28

object.assign()如何使用

这篇“object.assign()如何使用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“object.assign()如何
2023-07-04

WebComponent如何使用

本篇内容介绍了“WebComponent如何使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!正文WebComponent 是官方定义的自定
2023-07-05

Properties如何使用

本篇内容介绍了“Properties如何使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!01. 摘要Map 的实现类有 HashMap、
2023-06-16

filezilla如何使用

本篇内容介绍了“filezilla如何使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!filezilla使用教程1、首先打开软件,在上方输
2023-07-02
2024-04-02

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录