object-mapper
object-mapper copied to clipboard
Mapping is not lazy!
The map function loads all the attribute values at first, although I expect when I give mappings as lambda, the attribute values get read lazily, that is, if some attribute has been set to null or other function, the getattr of source object must not be called. The reason is that I am using your library for mapping SqlAlchemy objects to DTO ones. Deferred loading feature of SqlAlchemy causes Select N+1 problem when using your library.
Hi. Sorry for the very late answer - I have absolutely forgot to answer. Lazy evaluation is a good point. I'll look at it. But if you have a PR... :)
After a few minutes looking at thecode and found the problem when getmembers is called the code access all properties and this cause SQLAlchemy to fire all the relationship load in the model, even using the excluded argument will not avoid the problem.
I came up with one solution and would like to discuss:
From this: https://github.com/marazt/object-mapper/blob/b02c6d68c5bf86462aa8080aff3e93b133afd43e/mapper/object_mapper.py#L137-L142
To this:
from_obj_dict = {k: v for k, v in from_obj.__dict__.items() if not_private(k) and not_excluded(k)}
to_obj_dict = {k: v for k, v in inst.__dict__.items() if not_private(k)}
https://github.com/renanvieira/object-mapper/blob/264a50eb976bf9cd91b5ed850600975188ba58d2/mapper/object_mapper.py#L137-L139
I tested this over SQLAlchemy models in my company project and work like a charm. But this changes breaks the test test_mapping_creation_with_custom_dir because the way the test create the class properties doesn't show in __dict__.
I was thinking maybe we can include a flag like sqlalchemy=True|False in the mapper __init__ or maybe another mapper called something like SQLAlchemyObjectMapper?
Hi. I will check it and let you know. I hope that tomorrow. Thanks for the post 👍.
Thanks, Marazt! I'm really glad to contribute, this lib is helping a lot.
I just stumbled upon a problem on this solution, __dict__ does not list @property attributes, only dir() and getmembers().
I think it'll be better to create a module of ObjectMapper coupled with SQLAlchemy where we can check if one of them is a model and only in this case use __dict__ instead of getmembers()
Thanks, Marazt! I'm really glad to contribute, this lib is helping a lot.
I just stumbled upon a problem on this solution,
__dict__does not list@propertyattributes, onlydir()andgetmembers().I think it'll be better to create a module of
ObjectMappercoupled with SQLAlchemy where we can check if one of them is a model and only in this case use__dict__instead ofgetmembers()
Yes,
Such composition of ObjectMapper and SqlAlchemy make sense. Do you have prototype that can be updated to PR? I can start to work on it probably tomorrow.
I'll try to work on a Pull Request in the next couple of days.