将一个Python字典转换为正确的Python基础模型(BaseModel)pydantic类

huangapple go评论143阅读模式
英文:

Convert a python dict to correct python BaseModel pydantic class

问题

我要创建一个SendNotificationChannel实例,其中正确设置conditional_config,以使condition_prop成为ConditionalExpressionProps或CycleDurationTrendProps,根据字典的结构而定。例如,如果字典如下:

  1. {
  2. "id": "1",
  3. "customer_id": "abc",
  4. "conditional_config": {
  5. "cond_type": "EXPRESSION",
  6. "conditional_expression": ".s_num>10"
  7. }
  8. }

那么执行类似SendNotificationChannel(**dict)的操作应该将conditional_config.condition_prop设置为ConditionalExpressionProps,对于CycleDurationTrendProps也是类似的。

然而,当我这样做时,它却采用了BaseConditionalProps。

  1. >>> channel = {"conditional_config": {"cond_type": "EXPRESSION", "condition_prop":{"conditional_expression":"ALPHA"}}}
  2. >>> channel_obj = SendNotificationChannel(**channel)
  3. >>> channel_obj
  4. SendNotificationChannel(conditional_config=ConditionalConfig(cond_type=<ConditionType.EXPRESSION: 'EXPRESSION'>, condition_prop=BaseConditionalProps()))
  5. >>> channel_obj.conditional_config.condition_prop
  6. BaseConditionalProps()
  7. >>>

我想知道有人如何解决这个问题,或者我是否在处理这个问题的方式上有误。

英文:

My requirement is to convert python dictionary which can take multiple forms into appropriate pydantic BaseModel class instance. Following are details:

  1. class ConditionType(str, Enum):
  2. EXPRESSION = &#39;EXPRESSION&#39;
  3. CYCLE_DUR_TREND = &#39;CYCLE_DUR_TREND&#39;
  4. class ConditionalExpressionProps(BaseConditionalProps):
  5. conditional_expression: str
  6. class CycleDurationTrendProps(BaseConditionalProps):
  7. direction_up : bool = True
  8. n : int = Field(1, ge=1, le=1000)
  9. class ConditionalConfig(BaseModel):
  10. cond_type: ConditionType = ConditionType.EXPRESSION
  11. condition_prop: BaseConditionalProps
  12. class SendNotificationChannel(BaseModel):
  13. id: str
  14. customer_id: str
  15. conditional_config: Optional[ConditionalConfig]

I want to create a SendNotificationChannel instance with correct conditional_config set such that condition_prop becomes ConditionalExpressionProps or CycleDurationTrendProps based on the structure of dict.

For example, if dict is:

  1. {
  2. &quot;id&quot; : &quot;1&quot;,
  3. &quot;customer_id&quot; : &quot;abc&quot;,
  4. &quot;conditional_config&quot; : {
  5. &quot;cond_type&quot;: &quot;EXPRESSION&quot;,
  6. &quot;conditional_expression&quot; : &quot;.s_num&gt;10&quot;
  7. }
  8. }

then on doing something like SendNotificationChannel(**dict) should make the conditional_config.condition_prop of type ConditionalExpressionProps, and similarly for CycleDurationTrendProps.

However when I'm doing this, its taking BaseConditionalProps.

  1. &gt;&gt;&gt; channel = {&quot;conditional_config&quot; : {&quot;cond_type&quot;: &quot;EXPRESSION&quot;, &quot;condition_prop&quot;:{&quot;conditional_expression&quot;:&quot;ALPHA&quot;}}}
  2. &gt;&gt;&gt; channel_obj = SendNotificationChannel(**channel)
  3. &gt;&gt;&gt; channel_obj
  4. SendNotificationChannel(conditional_config=ConditionalConfig(cond_type=&lt;ConditionType.EXPRESSION: &#39;EXPRESSION&#39;&gt;, condition_prop=BaseConditionalProps()))
  5. &gt;&gt;&gt; channel_obj.conditional_config.condition_prop
  6. BaseConditionalProps()
  7. &gt;&gt;&gt;

I'd want to know how would someone solve this problem, or if I'm tackling this the incorrect way.

答案1

得分: 1

如果我正确理解您的问题,您可以使用 .parse_obj 方法来解决问题。此外,您需要更新 condition_prop 字段的类型。以下是示例代码:

  1. from enum import Enum
  2. from typing import Optional, Union
  3. from pydantic import BaseModel, Field
  4. class ConditionType(str, Enum):
  5. EXPRESSION = 'EXPRESSION'
  6. CYCLE_DUR_TREND = 'CYCLE_DUR_TREND'
  7. class BaseConditionalProps(BaseModel):
  8. pass
  9. class ConditionalExpressionProps(BaseConditionalProps):
  10. conditional_expression: str
  11. class CycleDurationTrendProps(BaseConditionalProps):
  12. direction_up : bool = True
  13. n : int = Field(1, ge=1, le=1000)
  14. class ConditionalConfig(BaseModel):
  15. cond_type: ConditionType = ConditionType.EXPRESSION
  16. condition_prop: Union[ConditionalExpressionProps, CycleDurationTrendProps]
  17. class SendNotificationChannel(BaseModel):
  18. id: str
  19. customer_id: str
  20. conditional_config: Optional[ConditionalConfig]
  21. channel_1 = {
  22. "id" : "1",
  23. "customer_id" : "abc",
  24. "conditional_config" : {
  25. "cond_type": "EXPRESSION",
  26. "condition_prop": {
  27. "conditional_expression" : ".s_num>10"
  28. }
  29. }
  30. }
  31. channel_1_obj = SendNotificationChannel.parse_obj(channel_1)
  32. print(channel_1_obj)
  33. # id='1' customer_id='abc' conditional_config=ConditionalConfig(cond_type=<ConditionType.EXPRESSION: 'EXPRESSION'>, condition_prop=ConditionalExpressionProps(conditional_expression='.s_num>10'))
  34. channel_2 = {
  35. "id" : "2",
  36. "customer_id" : "def",
  37. "conditional_config" : {
  38. "cond_type": "CYCLE_DUR_TREND",
  39. "condition_prop": {
  40. "n" : 10
  41. }
  42. }
  43. }
  44. channel_2_obj = SendNotificationChannel.parse_obj(channel_2)
  45. print(channel_2_obj)
  46. # id='2' customer_id='def' conditional_config=ConditionalConfig(cond_type=<ConditionType.CYCLE_DUR_TREND: 'CYCLE_DUR_TREND'>, condition_prop=CycleDurationTrendProps(direction_up=True, n=10))
英文:

If I understand your question correctly you can to use .parse_obj method for your problem. Also you need to update the condition_prop field type. The following code it is example:

  1. from enum import Enum
  2. from typing import Optional, Union
  3. from pydantic import BaseModel, Field
  4. class ConditionType(str, Enum):
  5. EXPRESSION = &#39;EXPRESSION&#39;
  6. CYCLE_DUR_TREND = &#39;CYCLE_DUR_TREND&#39;
  7. class BaseConditionalProps(BaseModel):
  8. pass
  9. class ConditionalExpressionProps(BaseConditionalProps):
  10. conditional_expression: str
  11. class CycleDurationTrendProps(BaseConditionalProps):
  12. direction_up : bool = True
  13. n : int = Field(1, ge=1, le=1000)
  14. class ConditionalConfig(BaseModel):
  15. cond_type: ConditionType = ConditionType.EXPRESSION
  16. condition_prop: Union[ConditionalExpressionProps, CycleDurationTrendProps]
  17. class SendNotificationChannel(BaseModel):
  18. id: str
  19. customer_id: str
  20. conditional_config: Optional[ConditionalConfig]
  21. channel_1 = {
  22. &quot;id&quot; : &quot;1&quot;,
  23. &quot;customer_id&quot; : &quot;abc&quot;,
  24. &quot;conditional_config&quot; : {
  25. &quot;cond_type&quot;: &quot;EXPRESSION&quot;,
  26. &quot;condition_prop&quot;: {
  27. &quot;conditional_expression&quot; : &quot;.s_num&gt;10&quot;
  28. }
  29. }
  30. }
  31. channel_1_obj = SendNotificationChannel.parse_obj(channel_1)
  32. print(channel_1_obj)
  33. # id=&#39;1&#39; customer_id=&#39;abc&#39; conditional_config=ConditionalConfig(cond_type=&lt;ConditionType.EXPRESSION: &#39;EXPRESSION&#39;&gt;, condition_prop=ConditionalExpressionProps(conditional_expression=&#39;.s_num&gt;10&#39;))
  34. channel_2 = {
  35. &quot;id&quot; : &quot;2&quot;,
  36. &quot;customer_id&quot; : &quot;def&quot;,
  37. &quot;conditional_config&quot; : {
  38. &quot;cond_type&quot;: &quot;CYCLE_DUR_TREND&quot;,
  39. &quot;condition_prop&quot;: {
  40. &quot;n&quot; : 10
  41. }
  42. }
  43. }
  44. channel_2_obj = SendNotificationChannel.parse_obj(channel_2)
  45. print(channel_2_obj)
  46. # id=&#39;2&#39; customer_id=&#39;def&#39; conditional_config=ConditionalConfig(cond_type=&lt;ConditionType.CYCLE_DUR_TREND: &#39;CYCLE_DUR_TREND&#39;&gt;, condition_prop=CycleDurationTrendProps(direction_up=True, n=10))

huangapple
  • 本文由 发表于 2023年1月6日 14:53:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/75027840.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定