我正在按照本教程进行调整,以适应我的需求,在本例中,执行一个 sql 模块,我需要在其中记录 webhook 从 gitlab 问题收集的数据。
对于数据库模块,我使用SQLAlchemy库和PostgreSQL作为数据库引擎。
所以,我想解决一些关于Pydantic库的使用的疑问,特别是这个例子
据我所知,Pydantic 是一个使用带有属性的类进行数据验证的库。
但我不太明白一些事情......Pydantic 的集成是绝对必要的吗?我理解使用 Pydantic 的目的,但我不明白使用 Pydantic 与 SQLAlchemy 模型的集成。
教程中,models.py
有以下内容:
from sqlalchemy import Boolean, Column, ForeignKey, Integer, String
from sqlalchemy.orm import relationship
from .database import Base
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, index=True)
email = Column(String, unique=True, index=True)
hashed_password = Column(String)
is_active = Column(Boolean, default=True)
items = relationship("Item", back_populates="owner")
class Item(Base):
__tablename__ = "items"
id = …
Run Code Online (Sandbox Code Playgroud) 我使用 Pydantic 对 API 的请求和响应进行建模。
我定义了一个User
类:
from pydantic import BaseModel
class User(BaseModel):
name: str
age: int
Run Code Online (Sandbox Code Playgroud)
我的 API 返回一个我检索的用户列表requests
并将其转换为字典:
users = [{"name": "user1", "age": 15}, {"name": "user2", "age": 28}]
Run Code Online (Sandbox Code Playgroud)
如何将此字典转换为User
实例列表?
我现在的解决方案是
user_list = []
for user in users:
user_list.append(User(**user))
Run Code Online (Sandbox Code Playgroud) 我用一些参数做了一个帖子,但其中一个返回“field required”和“value_error.missing”,但该字段在那里并且有一个值。查看 Postman 的输出。
在 schemas.py 中,字段定义如下:
class Message(BaseModel):
title: str
id: int
datim: Optional[datetime]
to_id: Optional[int]
from_id: Optional[int]
body: Optional[str]
class Config:
orm_mode = True
Run Code Online (Sandbox Code Playgroud)
那么它为什么要抱怨“身体”呢?
我有以下 pydantic 模型。
class SubModel(BaseModel):
columns: Mapping
key: List[str]
required: Optional[List[str]]
class Config:
anystr_strip_whitespace: True
extra: Extra.allow
allow_population_by_field_name: True
class MyModel(BaseModel):
name: str
config1: Optional[SubModel]
config2: Optional[Mapping]
class Config:
anystr_strip_whitespace: True
extra: Extra.allow
allow_population_by_field_name: True
Run Code Online (Sandbox Code Playgroud)
当我尝试dumps
对此进行操作时,我得到了model is not JSON serializable
from io import BytesIO
from orjson import dumps
bucket = s3.Bucket(bucket_name)
bucket.upload(BytesIO(dumps(data)), key, ExtraArgs={'ContentType': 'application/json'})
Run Code Online (Sandbox Code Playgroud)
错误 -
TypeError: Type is not JSON serializable: MyModel
Run Code Online (Sandbox Code Playgroud)
data
是一个普通的Python字典,其中有一个类型为item的项目MyModel
。尝试使用.json()
但得到dict has no attribute json
。
我被困在这里了。有人能帮我吗。
在普通的 python 类中,我可以定义类属性,例如
class Example:
x = 3
def __init__(self):
pass
Run Code Online (Sandbox Code Playgroud)
如果我接着做Example.x
or Example().x
,我就得到了3
。
当我继承 pydantic's 时BaseModel
,我不知道如何定义类属性,因为定义它们的通常方法被 BaseModel 覆盖。
例如:
class Example(BaseModel):
x = 3
print(Example.x)
--> type object 'Example' has no attribute 'x'
Run Code Online (Sandbox Code Playgroud)
我希望能够定义类级别属性。正确的方法/语法是什么?
在更改某些属性后,是否有任何明显的方法可以验证 pydantic 模型?
假设我创建一个简单的模型和对象:
from pydantic import BaseModel
class A(BaseModel):
b: int = 0
a=A()
Run Code Online (Sandbox Code Playgroud)
然后编辑它,使其实际上无效:
a.b = "foobar"
Run Code Online (Sandbox Code Playgroud)
我可以强制重新验证并期望ValidationError
提高 a 吗?
我试过
A.validate(a) # no error
a.copy(update=dict(b='foobar')) # no error
Run Code Online (Sandbox Code Playgroud)
所做的工作是
A(**dict(a._iter()))
ValidationError: 1 validation error for A
b
value is not a valid integer (type=type_error.integer)
Run Code Online (Sandbox Code Playgroud)
但这并不是很简单,我需要使用所谓的私有方法_iter
。
有干净的替代品吗?
抱歉,不精通Python。
我还没有找到该用例的文档。我如何获取请求正文,确保它是一个有效的 Json(任何有效的 json,包括数字、字符串、布尔值和空值,而不仅仅是对象和数组)并获取实际的 Json。使用 pydantic 强制 Json 具有特定的结构。
我正在尝试使用 Python 库创建一个动态模型pydantic
。我的输入数据是常规的dict
. 但是,(读取:其键)的内容dict
可能会有所不同。
我想知道如何动态创建pydantic
依赖于 的dict
内容的模型?
我创建了一个带有两个不同dict
s (inputs1
和inputs2
) 的玩具示例。我们假设嵌套dict
调用strategy
可能不同。基于strategy/name
我事先知道哪些字段将存在于strategy
. 我需要pydantic
基于创建模型strategy/name
。
from pydantic import BaseModel
inputs1 = {
"universe": {"name": "test_universe", "ccy": "USD"},
"price_src": "csv",
"strategy": {"name": "test_strat1"},
}
inputs2 = {
"universe": {"name": "test_universe", "ccy": "USD"},
"price_src": "csv",
"strategy": {"name": "test_strat2", "periods": 10},
}
class Universe(BaseModel):
name: str
ccy: str = "EUR" …
Run Code Online (Sandbox Code Playgroud) 对于如下 Pydantic 类,我想foo
通过应用replace
操作来转换字段:
from typing import List
from pydantic import BaseModel
class MyModel(BaseModel):
foo: List[str]
my_object = MyModel(foo="hello-there")
my_object.foo = [s.replace("-", "_") for s in my_object.foo]
Run Code Online (Sandbox Code Playgroud)
创建对象时,如何replace
在类中正确执行操作?如果没有 Pydantic,我会简单地在其中执行此操作__init(self, foo)
,但由于 Pydantic 创建了自己的__init__
实现,我不确定如何准确地进行。
我正在尝试将 MongoDB 数据解析为 pydantic 模式,但无法读取其_id
字段,该字段似乎从模式中消失了。
该问题肯定与对象属性前面的下划线有关。我无法更改_id
字段名称,因为这意味着根本不解析该字段。
请在下面找到我使用的代码(为了简化而使用int
而不是)ObjectId
from pydantic import BaseModel
class User_1(BaseModel):
_id: int
data_1 = {"_id": 1}
parsed_1 = User_1(**data_1)
print(parsed_1.schema())
class User_2(BaseModel):
id: int
data_2 = {"id": 1}
parsed_2 = User_2(**data_2)
print(parsed_2.schema())
Run Code Online (Sandbox Code Playgroud)
User_1
解析成功,因为它的_id
字段是必需的,但之后无法读取。
User_2
在上面的示例中,如果附加到 Mongo 则失败,但 Mongo 不提供任何id
字段,但_id
。
上面代码的输出如下:
User_1 {'title': 'User_1', 'type': 'object', 'properties': {}}
User_2 {'title': 'User_2', 'type': 'object', 'properties': {'id': {'title': 'Id', 'type': 'integer'}}, 'required': ['id']}
Run Code Online (Sandbox Code Playgroud) pydantic ×10
python ×7
python-3.x ×3
fastapi ×2
json ×1
mongodb ×1
orjson ×1
sql ×1
sqlalchemy ×1