使用datamodel-code-generator从GraphQL生成Pydantic模型

使用datamodel-code-generator从GraphQL生成Pydantic模型

datamodel-code-generator Pydantic model and dataclasses.dataclass generator for easy conversion of JSON, OpenAPI, JSON Schema, and YAML data sources. datamodel-code-generator 项目地址: https://gitcode.com/gh_mirrors/da/datamodel-code-generator

项目概述

datamodel-code-generator是一个强大的代码生成工具,能够将GraphQL模式定义自动转换为Python中的Pydantic模型。这个工具极大地简化了在Python项目中处理GraphQL数据的工作流程,特别是在类型安全和数据验证方面。

基础使用教程

安装与基本命令

首先需要安装datamodel-code-generator工具,安装完成后可以通过简单的命令行操作生成模型代码。

基础生成命令格式如下:

datamodel-codegen --input schema.graphql --input-file-type graphql --output model.py

示例解析

让我们通过一个图书管理系统的例子来理解这个过程。

GraphQL模式定义 (schema.graphql):

type Book {
  id: ID!  
  title: String
  author: Author
}

type Author {
  id: ID!  
  name: String
  books: [Book]
}

input BooksInput {
    ids: [ID!]!
}

input AuthorBooksInput {
    id: ID!
}

type Query {
  getBooks(input: BooksInput): [Book]
  getAuthorBooks(input: AuthorBooksInput): [Book]
}

生成的Pydantic模型 (model.py):

from __future__ import annotations
from typing import List, Optional, TypeAlias
from pydantic import BaseModel, Field
from typing_extensions import Literal

# 基本标量类型定义
Boolean: TypeAlias = bool
ID: TypeAlias = str
String: TypeAlias = str

class Author(BaseModel):
    books: Optional[List[Optional[Book]]] = Field(default_factory=list)
    id: ID
    name: Optional[String] = None
    typename__: Optional[Literal['Author']] = Field('Author', alias='__typename')

class Book(BaseModel):
    author: Optional[Author] = None
    id: ID
    title: Optional[String] = None
    typename__: Optional[Literal['Book']] = Field('Book', alias='__typename')

class AuthorBooksInput(BaseModel):
    id: ID
    typename__: Optional[Literal['AuthorBooksInput']] = Field(
        'AuthorBooksInput', alias='__typename'
    )

class BooksInput(BaseModel):
    ids: List[ID]
    typename__: Optional[Literal['BooksInput']] = Field(
        'BooksInput', alias='__typename'
    )

响应数据反序列化

在实际应用中,我们经常需要将GraphQL查询返回的JSON数据转换为Pydantic模型实例。

示例响应数据 (response.json):

{
  "getAuthorBooks": [
    {
      "author": {
        "id": "51341cdscwef14r13",
        "name": "J. K. Rowling"
      },
      "id": "1321dfvrt211wdw",
      "title": "Harry Potter and the Prisoner of Azkaban"
    }
  ]
}

反序列化代码 (main.py):

from model import Book

response = {...}  # 实际从API获取的响应数据

books = [Book.parse_obj(book_raw) for book_raw in response["getAuthorBooks"]]
print(books)

自定义标量类型处理

GraphQL允许定义自定义标量类型,datamodel-code-generator提供了灵活的方式来处理这些类型。

自定义标量示例 (schema.graphql):

scalar Long

type A {
  id: ID!
  duration: Long!
}

类型映射配置 (data.json):

{
  "Long": {
    "py_type": "int"
  }
}

生成命令:

datamodel-codegen --input schema.graphql --input-file-type graphql --output model.py --extra-template-data data.json

生成的模型:

Long: TypeAlias = int

class A(BaseModel):
    duration: Long
    id: ID
    typename__: Optional[Literal['A']] = Field('A', alias='__typename')

高级特性与最佳实践

  1. 循环引用处理:工具自动处理类型间的循环引用问题,如Book和Author之间的相互引用。

  2. 类型提示:生成的代码包含完整的类型提示,与现代Python开发实践完美契合。

  3. 默认值处理:可选字段会自动设置合理的默认值(如None或空列表)。

  4. GraphQL特性支持

    • 处理非空约束(!标记)
    • 支持列表类型
    • 保留类型名称信息(通过__typename字段)
  5. 扩展性:生成的模型可以轻松扩展,添加额外的方法或验证逻辑。

实际应用场景

  1. 前端与后端协作:前端开发者定义的GraphQL模式可以直接转换为后端使用的Python模型。

  2. API测试:快速生成测试数据结构和验证响应格式。

  3. 文档生成:结合Pydantic的文档功能,自动生成API文档。

  4. 数据验证:在接收GraphQL响应时进行严格的数据验证。

总结

datamodel-code-generator为Python开发者提供了从GraphQL模式到Pydantic模型的无缝转换能力,大大提高了开发效率和代码质量。通过自动生成的类型安全模型,开发者可以专注于业务逻辑的实现,而不必担心数据结构的定义和验证问题。

datamodel-code-generator Pydantic model and dataclasses.dataclass generator for easy conversion of JSON, OpenAPI, JSON Schema, and YAML data sources. datamodel-code-generator 项目地址: https://gitcode.com/gh_mirrors/da/datamodel-code-generator

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

颜妙瑶Titus

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值