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

usecase: how to get the object history data to track obj change in event? #49

Open
wangxin688 opened this issue Jul 10, 2023 · 2 comments

Comments

@wangxin688
Copy link

I try to get object change using following code, but MutableJSON has no history getted

def get_object_changes(obj):
    """Given a model instance, returns dict of pending
    changes waiting for database flush/commit.

    e.g. {
        "pre_change": {},
        "post_change": {},
        "diff": {}
    }
    """
    inspection = inspect(obj)
    changes = {
        "pre_change": {},
        "post_change": {},
        "diff": {},
    }
    for attr in class_mapper(obj.__class__).column_attrs:
        if getattr(inspection.attrs, attr.key).history.has_changes():
            if get_history(obj, attr.key)[2]:
                before = get_history(obj, attr.key)[2].pop()
                after = getattr(obj, attr.key)
                changes["pre_change"][attr.key] = before
                changes["post_change"][attr.key] = after
                if before != after:
                    if before or after:
                        changes["diff"][attr.key] = {"before": before, "after": after}
    return jsonable_encoder(changes)
@edelooff
Copy link
Owner

I don't know the exact behaviour of get_history, assuming this is a SQLAlchemy function, but assuming it gets the previous object from the session, what you are showing is expected behaviour.

The object gets modified in-place, meaning that the reference to the "previous" value refers to the same object as the "current", and there is no difference between them.

Making changes like this detectable would require some level of explicit (deep) copying of the original data, which would be very unexpected.

You might be able to subclass the MutableJSON type to enable something like that, but it's not something suitable for the basic behaviour I think.

@wangxin688
Copy link
Author

wangxin688 commented Jul 10, 2023

I don't know the exact behaviour of get_history, assuming this is a SQLAlchemy function, but assuming it gets the previous object from the session, what you are showing is expected behaviour.

The object gets modified in-place, meaning that the reference to the "previous" value refers to the same object as the "current", and there is no difference between them.

Making changes like this detectable would require some level of explicit (deep) copying of the original data, which would be very unexpected.

You might be able to subclass the MutableJSON type to enable something like that, but it's not something suitable for the basic behaviour I think.

sqlalchemy.orm.attributes import get_history will return History object which has three attr:
added : the collection of elements added to the attribute

unchanged : the collection of elements that have not changed on the attribute

deleted : the collection of elements that have been deleted from the attribute.
I guess you are right, i might need to use subclass to implement this

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