【问题标题】:How to inflect from snake case to camel case post the pydantic schema validations如何在 pydantic 模式验证后从蛇案例转变为骆驼案例
【发布时间】:2021-08-31 20:25:09
【问题描述】:

我可以找到一种方法,通过使用别名生成器将基于驼峰类型的请求正文转换为蛇型,但是对于我的回应,我再次想将蛇型转换为驼峰类型发布到架构验证。有什么办法可以实现吗?

示例: 我确实有一个如下的python dict,

{
 "title_name": "search001",
 "status_type": "New" 
}

然后发布到 pydantic 模式验证,我的 dict 应该将蛇案例类型转换为骆驼案例,如下所示,

{
 "titleName": "search001",
 "statusType": "New" 
}

如何定义一个 pydantic 模式来解决上述问题?

提前致谢。

【问题讨论】:

    标签: python pydantic


    【解决方案1】:

    我强烈建议你试试这个。使用marshmallow

    from marshmallow import Schema, fields
    
    
    def camelcase(s):
        parts = iter(s.split("_"))
        return next(parts) + "".join(i.title() for i in parts)
    
    
    class CamelCaseSchema(Schema):
        """Schema that uses camel-case for its external representation
        and snake-case for its internal representation.
        """
    
        def on_bind_field(self, field_name, field_obj):
            field_obj.data_key = camelcase(field_obj.data_key or field_name)
    
    
    # -----------------------------------------------------------------------------
    
    
    class UserSchema(CamelCaseSchema):
        first_name = fields.Str(required=True)
        last_name = fields.Str(required=True)
    
    
    schema = UserSchema()
    loaded = schema.load({"firstName": "David", "lastName": "Bowie"})
    print(loaded)  # => {'last_name': 'Bowie', 'first_name': 'David'}
    dumped = schema.dump(loaded)
    print(dumped)  # => {'lastName': 'Bowie', 'firstName': 'David'}
    

    你可以在那里了解更多信息https://marshmallow.readthedocs.io/en/stable/examples.html

    【讨论】:

      【解决方案2】:

      您可以使用Alias Generator

      from pydantic import BaseModel
      
      
      def to_snake_case(string: str) -> str:
          return ''.join(['_' + i.lower() if i.isupper() else i for i in string]).lstrip('_')
      
      
      class MyModel(BaseModel):
          titleName: str
          statusType: str
      
          class Config:
              alias_generator = to_snake_case
      
      
      data = {
          "title_name": "search001",
          "status_type": "New"
      }
      print(MyModel(**data).dict()) # {'titleName': 'search001', 'statusType': 'New'}
      
      

      【讨论】:

        【解决方案3】:

        您可以在.json.dict 中使用别名生成器和kwarg by_alias 的组合:

        from pydantic import BaseModel,Field
        
        def to_camel(string: str) -> str:
            string_split = string.split('_')
            return string_split[0]+''.join(word.capitalize() for word in string_split[1:])
        
        
        class Foo(BaseModel):
            title_name:str
            status_type:str
            class Config:
                alias_generator = to_camel
        
        f = Foo.parse_raw("""
        {
         "titleName": "search001",
         "statusType": "New" 
        }
        """)
        print(f) # title_name='search001' status_type='New'
        print(f.json(by_alias=True)) # {"titleName": "search001", "statusType": "New"}
        print(f.json()) # {"title_name": "search001", "status_type": "New"}
        

        另外,您可以在Config 类中添加allow_population_by_field_name=True,以便您可以使用原始字段名或别名来解析/初始化模型。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-02-10
          • 2019-10-30
          • 1970-01-01
          • 2016-01-16
          • 1970-01-01
          • 2022-06-11
          • 1970-01-01
          • 2020-05-03
          相关资源
          最近更新 更多