Tracking model changes in SQLAlchemy

后端 未结 3 811
半阙折子戏
半阙折子戏 2021-01-31 18:43

I want to log every action what will be done with some SQLAlchemy-Models.

So, I have a after_insert, after_delete and before_update hooks, where I will save previous and

3条回答
  •  既然无缘
    2021-01-31 19:08

    I had a similar problem but wanted to be able to keep track of the deltas as changes are made to sqlalchemy models instead of just the new values. I wrote this slight extension to davidism's answer to do that along with slightly better handling of before and after, since they are lists sometimes or empty tuples other times:

      from sqlalchemy import inspect
    
      def get_model_changes(model):
        """
        Return a dictionary containing changes made to the model since it was 
        fetched from the database.
    
        The dictionary is of the form {'property_name': [old_value, new_value]}
    
        Example:
          user = get_user_by_id(420)
          >>> ''
          get_model_changes(user)
          >>> {}
          user.email = 'new_email@who-dis.biz'
          get_model_changes(user)
          >>> {'email': ['business_email@gmail.com', 'new_email@who-dis.biz']}
        """
        state = inspect(model)
        changes = {}
        for attr in state.attrs:
          hist = state.get_history(attr.key, True)
    
          if not hist.has_changes():
            continue
    
          old_value = hist.deleted[0] if hist.deleted else None
          new_value = hist.added[0] if hist.added else None
          changes[attr.key] = [old_value, new_value]
    
        return changes
    
      def has_model_changed(model):
        """
        Return True if there are any unsaved changes on the model.
        """
        return bool(get_model_changes(model))
    

提交回复
热议问题