konradhalas / dacite

Simple creation of data classes from dictionaries.
MIT License
1.72k stars 106 forks source link

Support of a custom mapping to the fields with different names #225

Open scrobot opened 1 year ago

scrobot commented 1 year ago

I have one common problem. My model/entity has a field that might be related to the DTO but with different naming and type.

@dataclass
class User:
    secret: str
    name: str
    created_at: datetime = datetime.now()
    updated_at: datetime = datetime.now()
    _id: ObjectId = ObjectId()

@dataclass
class UserResponse(BaseModel):
    id: str
    name: str
    created_at: datetime
    updated_at: datetime

I'm of opinion that the best way to resolve this problem would be to add some customization to the mapping

    def find_user(self, user_id) -> UserResponse:
        data = self.user_repository.get_user_by_id(user_id)
        return from_dict(
            UserResponse,
            data,
            config=Config(
                cast=[ObjectId, datetime],
                mapping={
                    id: lambda value: str(value._id)
                }
            )
        )

Or maybe apply some "magic" :) but I'm not pretty sure) Just for the thinking about.

@dataclass
@map({'id': '_id'})
class UserResponse(BaseModel): 
    id: str
    name: str
    created_at: datetime
    updated_at: datetime
jmhodges-color commented 1 year ago

Just run into this with REST API dictionaries that include a self key (that's the canonical URL back for the object) which is unusable as a field name in dataclasses and get you errors like:

SyntaxError: duplicate argument 'self' in function definition

An alternative to the decorator implementation would be to use field(metadata=...), but either could work.