python-3.x 如何在验证后为Pydantic模型的字段分配不同类型的值?

esbemjvw  于 2023-03-31  发布在  Python
关注(0)|答案(1)|浏览(137)

我有一个csv文件,它有youtube的网址和时间戳。

https://www.youtube.com/watch?v=dsnLcaNhXd6o,0:13-0:20;0:25-0:31;0:36-0:40
https://www.youtube.com/watch?v=d8InLcaNhXd6o,0:43-0:52;0:56-1:07
https://www.youtube.com/watch?v=Inji8LcaNhXd6o,0:13-0:20;0:25-0:31;0:36-0:40;0:43-0:52;0:56-1:07;1:15-1:25;1:28-1:40

我需要将csv文件转换为pydantic对象,以便我可以验证csv文件并将其传递给执行某些过程。

with open(csv_file, mode ='r') as file:
        csvFile = csv.reader(file)
        csvList = list(enumerate(csvFile))

我有以下Pydantic模型:

class TimeStamp(BaseModel):
    start_min: int
    start_sec: int
    end_min: int
    end_sec: int

class VideoDetail(BaseModel):
    row_index: int
    url: str
    timestamps: List[TimeStamp]

class VideoList(BaseModel):
    entry: List[VideoDetail]

现在,我需要将csvList传递给VideoList模型,并执行一些验证,获得一个VideoList对象。
首先,list(enumerate(csvFile))将返回tupleslist,其中包含row indexrow
example

csvList = list(enumerate(csvFile))
print(csvList)

output

[
(0, "https://www.youtube.com/watch?v=dsnLcaNhXd6o","0:13-0:20;0:25-0:31;0:36-0:40"),
(1, "https://www.youtube.com/watch?v=d8InLcaNhXd6o","0:43-0:52;0:56-1:07"),
(2, "https://www.youtube.com/watch?v=d8InLcaNhXd6o","0:43-0:52;0:56-1:07")
]

现在,当我将csvList模型传递给VideoList模型时,timestamp将作为字符串传递。但是我如何将它传递到TimeStamp对象的列表中呢?
我尝试在VideoDetail模型中的timestamp字段中添加一个验证器,并将字符串拆分为一个时间戳列表,然后返回它。但它不会工作,因为它会抛出错误,因为timestamp的类型不匹配。

wvt8vs2t

wvt8vs2t1#

基本上,这个想法是你必须将时间戳字符串拆分成多个片段,以提供给pydantic模型的各个变量:时间戳
我正在使用一个验证器函数来做同样的事情。验证器中的pre=True确保这个函数在赋值之前运行。在验证器函数中:-
1.时间戳字符串 (例如0:43-0:52;0:56-1:07) 先被**分割;获取时间戳的字符串列表。
1.然后它循环遍历每个这样的时间戳-字符串 (ex 0:43-0:52),并将每个时间戳拆分为
-以获得开始时间和结束时间
1.最后,它将每个开始时间和结束时间 (例如0:43)
:**拆分,将每个时间转换为整数,并添加到列表中
(我用字典代替了元组。你可以用元组)

class TimeStamp(BaseModel):
    start_min: int
    start_sec: int
    end_min: int
    end_sec: int

class VideoDetail(BaseModel):
    row_index: int
    url: str
    timestamps: List[TimeStamp]
        
    @validator("timestamps", pre=True)
    def createTimestamps(cls, value):
        timestampslist = []
        if isinstance(value, str):
            timestamplist_str = value.split(";")
            for eachTimestamp in timestamplist_str:
                start_time_str, end_time_str = eachTimestamp.split("-")
                t = TimeStamp(start_min=int(start_time_str.split(":")[0]),
                              start_sec = int(start_time_str.split(":")[1]),
                              end_min=int(end_time_str.split(":")[0]),
                              end_sec = int(end_time_str.split(":")[1]))
                timestampslist.append(t)
        return timestampslist

class VideoList(BaseModel):
    entry: List[VideoDetail]
        
csvList = [
    {"row_index":0, "url": "https://www.youtube.com/watch?v=dsnLcaNhXd6o", "timestamps":"0:13-0:20;0:25-0:31;0:36-0:40"},
    {"row_index":0, "url": "https://www.youtube.com/watch?v=wcsnLcad6d", "timestamps":"0:13-0:20;0:25-0:31;0:36-0:40"},
    {"row_index":0, "url": "https://www.youtube.com/watch?v=LcdshXe6o", "timestamps":"0:13-0:20;0:25-0:31;0:36-0:40"},
]

vs = VideoList(entry=csvList)

相关问题