Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to parse json string back to AvroModel #638

Closed
RuiLoureiro opened this issue May 24, 2024 · 3 comments
Closed

How to parse json string back to AvroModel #638

RuiLoureiro opened this issue May 24, 2024 · 3 comments

Comments

@RuiLoureiro
Copy link

RuiLoureiro commented May 24, 2024

Hi! I'm trying to initialize an AvroModel from a json string.

I tried using parse_obj, but the strings corresponding to datetime are not parsed into a datetime object.

Example

import json
import dataclasses
from datetime import datetime

from dataclasses_avroschema.schema_generator import AvroModel


@dataclasses.dataclass
class MyModel(AvroModel):
    a: str
    b: datetime

    class Meta:
        namespace = "my.namespace"

m = MyModel(a="123", b=datetime.now())

parsed = MyModel.parse_obj(json.loads(m.to_json()))

# prints 'MyModel(a='123', b='2024-05-24T12:28:49')'
print(parsed)

Is this expected behavior? And is there any alternative way to achieve this?

@marcosschroh
Copy link
Owner

Hi,

Ideally we want to have the original object. The problem is that dataclasses are not really smart, then we are using dacite to make the conversion from dict to class instances. To solve your problem right away you can use custom dacite config using type_hooks:

import json
import dataclasses
from datetime import datetime

from dataclasses_avroschema.schema_generator import AvroModel

def parse_datetime(value):
     return datetime.strptime(value, "%Y-%m-%dT%H:%M:%S")



@dataclasses.dataclass
class MyModel(AvroModel):
     a: str
     b: datetime

     class Meta:
         namespace = "my.namespace"
         dacite_config = {"type_hooks": {datetime: parse_datetime}}

m = MyModel(a="123", b=datetime.now())

print(MyModel.parse_obj(json.loads(m.to_json())))

Out[33]: MyModel(a='123', b=datetime.datetime(2024, 5, 24, 16, 29, 3))

I will add the hook in the library so it will be easier for end users. You need to take into account that if the datetime string format changes then it won't work.

@RuiLoureiro
Copy link
Author

Thank you for the quick reply @marcosschroh.
I added the dacite type hooks and it works as expected, so I'm closing the issue

@marcosschroh
Copy link
Owner

@RuiLoureiro You're welcome. I have added the missing dacite hooks. If you update to the latest version (0.60.0) you can remove your custom hook (everything should work effortless from end user point of view)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants