object-mapper icon indicating copy to clipboard operation
object-mapper copied to clipboard

Mapping is not lazy!

Open kamyar1979 opened this issue 7 years ago • 6 comments

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.

kamyar1979 avatar Jun 13 '18 13:06 kamyar1979

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... :)

marazt avatar Sep 29 '18 06:09 marazt

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?

renanvieira avatar Feb 17 '19 21:02 renanvieira

Hi. I will check it and let you know. I hope that tomorrow. Thanks for the post 👍.

marazt avatar Feb 24 '19 21:02 marazt

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()

renanvieira avatar Feb 26 '19 03:02 renanvieira

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()

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.

marazt avatar Feb 26 '19 21:02 marazt

I'll try to work on a Pull Request in the next couple of days.

renanvieira avatar Feb 27 '19 22:02 renanvieira